前端指南 前端指南
指南
资源
  • 刷力扣 (opens new window)
  • 手写题 (opens new window)
  • 归档
  • 分类
  • 标签
  • 关于我
  • 关于本站
GitHub (opens new window)

Seognil LC

略懂点前端
指南
资源
  • 刷力扣 (opens new window)
  • 手写题 (opens new window)
  • 归档
  • 分类
  • 标签
  • 关于我
  • 关于本站
GitHub (opens new window)
  • TypeScript 入门指南

    • TypeScript 简介
      • 什么是 TypeScript
      • 为什么要用 TypeScript
    • 学习 TypeScript
      • 概览
      • 学习路线
    • 资料
      • 概览
      • 自学教材
      • 进阶/实战
    • TypeScript 知识体系
      • 如何运行 TypeScript
      • TypeScript 主要概念
    • TypeScript 典型代码
      • TypeScript 基本语法
      • TypeScript 实用代码
    • TypeScript 相关
      • 泛型中的命名习惯
      • 从 JS 迁移到 TS
      • TypeScript 和 Flow
      • TypeScript 是如何工作/运行的
      • TypeScript 是如何基于 JavaScript 被开发出来的
      • TypeScript 有哪些不足
  • note
  • frontend
  • web
Seognil LC
2019-11-22
目录

TypeScript 入门指南

TypeScript 入门指南

# TypeScript 简介

# 什么是 TypeScript

一个 JavaScript 超集,包含类型系统,以及其他一些功能。

随着 Promise、Generators 等 API 进入 JS 标准,
TS 和 JS 在这些 API 方面的差别在变小,
但 TS 还有一些独有特性,这些特性才是和 JS 的主要区别:

  • 类型系统、type-checking
  • 类型(自动)推导、auto-completion

# 为什么要用 TypeScript

  • 提升代码健壮性
  • 面向接口编程(代码自解释,并行开发)
  • 静态检查可以提高开发效率
  • 减少开发时(人工推导带来的)认知负荷

# 学习 TypeScript

# 概览

  • 耗时:从入门到熟悉需要大约 20~40 小时(个人估计)
  • 难点:
    • 理解 JS 中没有的 TS 特性
    • 训练 TS 的高级用法(泛型、交集、条件等)
  • 工具:
    • TypeScript (opens new window)
    • ts-node (opens new window)
    • VS Code

# 学习路线

  • 前置学习
    • JavaScript 学习指南
    • 理解编程理念
      • 静态类型
      • Object Oriented Programming
      • Functional Programming
  • 学习 TypeScript
    • (学习 JavaScript)
    • 学习和使用 TypeScript 常用特性
      • 学习泛型和类型推导——TS 最难的部分之一
    • 尝试将以前写的 JS 代码转换成 TS 版本
    • 了解 @types (DefinitelyTyped (opens new window))
  • 实战
    • 写业务时逐步使用 TS (包括业务代码和 npm 包)
    • package 开发打包和声明文件
  • 进阶
    • 学习 TS 的高级用法
    • 阅读一些用库的 TS 相关源码(比如 redux (opens new window))
  • 迷思
    • 如何将 Object.keys 转换成 enum
    • 如何把数组转换成字面量类型
    • 如何给复杂的处理函数写类型
    • 如何写一个类型表示排除 undefined 的 any

# 资料

# 概览

  • 编程漫谈
    • 编程语言的类型系统为何如此重要? (opens new window)
    • 弱类型、强类型、动态类型、静态类型语言的区别是什么? (opens new window)
  • 生态
    • 编译工具 - 2018 年 JavaScript 明星项目 (opens new window)
  • TS
    • TypeScript 体系调研报告 (opens new window)
    • TypeScript 解决了什么痛点? (opens new window)
    • 浅谈 TypeScript 类型系统 (opens new window)
    • 随着 TypeScript 继续普及,会不会出现直接跑 TypeScript 的运行时? (opens new window)
    • The TypeScript Tax (opens new window)

# 自学教材

  • 快速入门
    • TypeScript - The Basics (opens new window):12 分钟,历史背景、基本使用、语法简介
    • VS Code - IntelliSense (opens new window):前 3 分钟,TS 在 VS Code 的自动完成中起到的作用
    • Working with TypeScript in Visual Studio Code (opens new window):10 分钟,在 VS Code 中的使用 TS
    • TypeScript - Learn X in Y minutes (opens new window):语法速查表
  • 社区文档
    • TypeScript for Beginner Programmers (opens new window):几篇入门文章(排版不错:)
      • TypeScript Generics for People Who Gave Up on Understanding Generics (opens new window):泛型入门
    • TypeScript 入门教程 (opens new window):比较丰富的入门文档(进阶章节是指高级特性)
    • 狡猾的 TypeScript: 易错点梳理 (opens new window):几道基本概念题
  • 官方文档(及汉化)
    • Documentation - TypeScript (opens new window):官方文档(最新)
      • Do's and Don'ts (opens new window):一些最佳实践贴士
    • TypeScript-Handbook (opens new window):社区汉化版(尽量保持官方同步)
  • 在线调试(TS 检查、编译到 JS)
    • TypeScript Playground (opens new window):官方的
    • Babel - Try it out (opens new window):Babel 的

# 进阶/实战

  • TS 语言
    • 视频
      • Fun Times with Advanced TypeScript (opens new window):25 分钟,包含很多 TS 进阶用法(2018 年)
    • 深入理解 TypeScript
      • TypeScript Deep Dive (opens new window):英文版
      • 深入理解 TypeScript (opens new window):社区汉化版
    • Effective TypeScript
      • Effective TypeScript (opens new window):原书 Oreilly 购买链接
      • Effective Typescript:使用 Typescript 的 n 个技巧 - 杨健 (opens new window)
      • Effective Typescript - 杨健 (opens new window)
    • 文章
      • Advanced Types (opens new window):官方文档中的「高级类型」章节
      • TypeScript Evolution (opens new window):TS 语言特性,系列文章
    • TS 进阶概念解析
      • The unknown Type in TypeScript (opens new window)
      • infer - 深入理解 TypeScript (opens new window)
      • TypeScript 中的 never 类型具体有什么用? (opens new window)
      • 类型推导
        • TypeScript 类型推导趣事一则 (opens new window)
        • Typescript Tips: 动态重载实现廉价版 dependent type (opens new window)
  • 开发
    • TS + 框架
      • 用 TypeScript 写 React & Redux - 完全指南 (opens new window)
    • Rollup 打包
      • How to bundle a npm package with TypeScript and Rollup (opens new window)
      • Building and publishing a module with TypeScript and Rollup.js (opens new window)
    • 杂项
      • TS 常见问题整理 (opens new window):TS 语言、tsconifg、React + TS

# TypeScript 知识体系

# 如何运行 TypeScript

  • 命令行命令
    • tsc,官方编译器
      • 安装 npm install -g typescript
    • ts-node,TS + Node
      • 安装 npm install -g ts-node
    • parcel, 自动检测运行
      • 安装 npm install -g parcel
  • TS 运行配置
    • Compiler Options (opens new window):编译选项
    • tsconfig.json (opens new window):配置文件
  • 工程化
    • 工具
      • types-checker (opens new window):自动安装 @types
      • DefinitelyTyped (opens new window):@types 官网
    • ESLint
      • Getting Started with ESLint (opens new window):ESLint 官方教程
      • @typescript-eslint/parser (opens new window):ESLint 的 TS 插件
    • 打包插件
      • @babel/preset-typescript (opens new window):babel 的
      • rollup-plugin-typescript2 (opens new window):rollup 的

# TypeScript 主要概念

  • TS 类型识别模式
    • Duck Typing (opens new window)
    • 类型推断 (opens new window)
  • TS 类型系统
    • type 类型别名、interface 接口
    • 变量声明/使用 (opens new window)
      • const const declarations (opens new window)
      • ! Non-null assertion operator (opens new window)
    • 基础类型 (opens new window)
      • JS 基本类型 number、string、boolean、undefined、null
      • Array、元组 Tuple (opens new window) (严格的、退化的数组)
      • any 任意类型、never 永不、void 空值(一般用于函数返回 undefined)
      • unknown (opens new window)
      • 枚举 (opens new window) Enums
    • 函数 (opens new window)
      • 函数的多种定义方式
      • this this 参数 (opens new window)
      • Overloads 重载 (opens new window)
    • 接口 (opens new window) interface
      • ? Optional Properties (opens new window)
      • readonly Readonly properties (opens new window)
      • Indexable Types (opens new window) 可索引类型
        • { [x: string]: number }
      • implements、extends
      • Hybrid Types (opens new window) 混合类型,JS 中允许的 函数 + 对象字段
    • 类 (opens new window) class
      • extends、implements、abstract
      • public/private/protected,简写法(constructor 参数)
      • readonly
      • get/set
      • static
    • 泛型 (opens new window) Generics
    • 装饰器 (opens new window) Decorators
  • TS 类型操作
    • 声明合并 (opens new window)
    • 高级类型 (opens new window)
      • | Union 联合类型、& Intersection 交叉类型
      • 类型收缩(Type Narrowing)(推断)
        • 控制流分析(Control Flow Based Type Analysis (opens new window))
        • 类型保护(Type Guard (opens new window))
          • as、in、is、typeof、instanceof
        • 可辨识联合(Discriminated Unions (opens new window))
      • 字面量类型(Literal Types)(类似枚举的联合类型)
      • 索引类型 Index types (opens new window)、映射类型 Mapped types (opens new window)
        • keyof
        • -? What does -? mean in TypeScript? (opens new window)
      • 条件类型(Conditional Types (opens new window))
        • T extends U ? X : Y
        • infer
    • Utility Types 工具类型 (opens new window)
      • Partial<T>
      • Readonly<T>
      • Record<K,T>
      • Pick<T,K>
      • Omit<T,K>
      • Exclude<T,U>
      • Extract<T,U>
      • NonNullable<T>
      • Parameters<T>
      • ConstructorParameters<T>
      • ReturnType<T>
      • InstanceType<T>
      • Required<T>
      • ThisParameterType
      • OmitThisParameter
      • ThisType<T>

# TypeScript 典型代码

# TypeScript 基本语法

Check TypeScript - Learn X in Y minutes (opens new window)

// ts-node

// * -------------------------------- 基本

// * ---------------- 基本类型

let isDone: boolean = false;
let lines: number = 42;
let lastName: string = 'Anders';

type MyList = number[];

let list: MyList = [1, 2, 3];

// * ---------------- 函数的几种声明方式

let square = (n: number): number => n * n;
let square2: (n: number) => number = (n) => n * n;

type Sq = (n: number) => number;
let square3: Sq = (n) => n * n;

interface Sq4 {
  (n: number): number;
}
let square4: Sq4 = (n) => n * n;

// * ---------------- 枚举

enum Color {
  Red = 'Red',
  Green = 'Green',
  Blue = 'Blue',
}

// * ---------------- 接口、类

interface CarInterface {
  model: string;
  radio?;
  getYear(): any;
}

class Car implements CarInterface {
  constructor(
    readonly model,
    private engine,
    public radio?,
  ) {} // 简写法

  static Manufacturer: string = 'BMW';
  getYear() {}
}

// * ---------------- 泛型

class Observable<T> {
  constructor(public value: T) {}
}

let myOb: Observable<number> = new Observable(2);

// * -------------------------------- 示例

// * ---------------- 接口、对象

interface MyDict {
  type: string;
  [name: string]: string; // 可索引
}

const dict: MyDict = {
  type: 'a dict',
  num: 233, // Error!
  word: 'hello', // Valid
};

// * ---------------- 递归的声明

type NumVal = 1 | 2 | 3 | NumVal[];
const nestArr: NumVal = [1, 2, 3, [1, 2, [3]]];
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81

# TypeScript 实用代码

# 联合转交集

type UnionToIntersection<U> = (
  U extends any ? (k: U) => void : never
) extends (k: infer I) => void
  ? I
  : never;
1
2
3
4
5

# 复杂的类型声明

infer - 深入理解 TypeScript (opens new window)

通过编写泛型和类型推断,能够拥有更准确的类型,
能保证业务代码拥有更充分的类型提示,提升代码整体质量。

type MapEveryToPromise<T extends object> = {
  [K in keyof T]: T[K] extends infer P ? Promise<P> : never;
};

const dataPool = {
  key1: 1,
  key2: 'hello',
  // ...
};

const advanceDataPool: MapEveryToPromise<typeof dataPool> =
  {
    key1: Promise.resolve(1),
    key2: Promise.resolve('hello'),
    // ...
  };
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

# TypeScript 相关

# 泛型中的命名习惯

很多代码中使用泛型,一般只使用一个大写字母,
这些实际相当于助记符,是缩写。

  • T (for Type)
  • E (for Element)
  • K (for Key)
  • V (for Value)
  • U 没找到出处…
    推测是 T 的后一位字母,就像 i, j, k 一样…
    也可能是指 Union

其他根据具体上下文可以同样推测:

  • S State
  • A Action

# 从 JS 迁移到 TS

Migrating from JavaScript (opens new window)

  • 注意!
    • 不要一边迁移一边修改代码逻辑
    • 不要在低测试覆盖率时迁移
    • 初期无需写太严谨的类型(为了开发效率)
    • 别忘记写 Type 的测试
    • 不要急着上线
  • 步骤
    • 第一阶段
      • 确保测试全部通过
      • 把 .js 文件重命名成 .ts
      • 修复类型检查错误或 TS 编译器报错
      • 别改代码逻辑
      • 确保测试全部通过
    • 第二阶段
      • 确保测试全部通过
      • 禁止隐式 any ({"noImplicitAny": true })
      • 尽量明确类型
        • 安装依赖的 @types (DefinitelyTyped (opens new window))
        • 实在不行用显式的 any
      • 确保测试全部通过
    • 第三阶段
      • 逐步升级,小步 commit
      • 打开全部的 strict 选项 (Compiler Options (opens new window))
      • 将显式 any 替换成具体类型
      • 尽力避免不安全类型声明

# TypeScript 和 Flow

Flow (opens new window) 是另一个 JS + type 超集,来自 Facebook。
TypeScript 来自微软,在特性上更丰富。

现在 TypeScript 领先 Flow,
几乎成为了新的 JS 开发标准了(尤其是大型工程)。

# TypeScript 是如何工作/运行的

不严谨但简单的理解:

  • 发布和执行前编译,完全退化成合法 JS
    • 类型系统全部丢弃
    • 无法丢弃的特性会被转义(比如 enum => Object)

可以尝试 Babel 在线编译 (opens new window) 来理解

TypeScript 编译原理 - 深入理解 TypeScript (opens new window)

# TypeScript 是如何基于 JavaScript 被开发出来的

这个问题需要扎实的 CS 基础作为铺垫…

如何看懂 typescript 核心源码,并可以参照 typescript 写一个类似的项目? (opens new window)

# TypeScript 有哪些不足

目前不支持高阶泛型

Allow classes to be parametric in other parametric classes (opens new window)

导致让这个 demo typescript-generic-problem (opens new window)
中的全部代码都拥有准确的类型是一件很困难的事情,
只能修改业务代码,或手动进行类型声明来妥协。

#编程语言#TypeScript#基础
上次更新: Jan 29, 2022 6:01 PM
最近更新
01
Linux Shell 快速入门笔记
11-18
02
我的 Web 前端开发知识体系 (2022)
01-29
03
游戏环境研究笔记(2022-01)
01-16
更多文章>
Theme by Vdoing | Copyright © 2019-2022 Seognil LC | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式