高级类型
交叉类型
操作符:&
,交叉类型并不是交集,在 Typescript 里其实是并集的意思,即新生成的类型,会拥有所有子类型的特性
联合类型
操作符:|
,联合类型必须做类型校验,如string | number
,只能访问它们中共有的属性或者方法
keyof T
索引类型查询操作符。 对于任何类型 T, keyof T 的结果为 T 上已知的公共属性名的联合
node
1 | let person: Person = { |
类型约束 extends
1 | type BaseType = string | number | boolean |
映射类型
in
关键字
在 JS 中我们可以通过 for…in 遍历出一个 object{} 的所有 key 然后进行一些逻辑处理。在 TS 中是否有类似的功能用于遍历 interface{}, { [ K in P ] : T }
1 | type Item = { a: string, b: number, c: boolean }; |
keyof Item
得到的是a | b | c
,那么type Copy = { [K in keyof Item]: Item[K] }
的结果就是type Copy = { a: string, b: number, c: boolean }
映射类型也可以有操作符:
1 | type Coord = { |
但是映射类型也有局限性,如果类型本省就带有操作符,通过映射之后,无法去除属性上已经存在的装饰符;因此,社区又在 TS2.8 又对其进行了完善,可以在上面的装饰符添加 - 或 + 符号:
1 | type CoordOptional = { |
条件类型
联合类型在 extends 时会默认进行如下转换:(A | B) extends U ? X : Y ----> (A extends U ? X : Y) | (B extends U ? X : Y)
分析一个条件类型:
1 | type Diff<T, U> = T extends U ? never : T |
拆解分析:
1 | Diff<'a', 'a' | 'e'> | Diff<'b', 'a' | 'e'> | Diff<'c', 'a' | 'e'> |
TypeScript 内置类型
Partial
将类型 T 的所有属性标记为可选属性
1 | type Partial<T> = { |
Record<K, T>
逐个遍历,映射 K 的类型为 T, 返回{K1: T, K2: T,…}
1 | type Record<K extends keyof any, T> = { |
Required
Required 将类型 T 的所有属性标记为必选属性
1 | type Required<T> = { |
Pick<T, K>
从 T 中获取属性 K
1 | type Pick<T, K extends keyof T> = { |
Exclude<T, U>
移除 T 中的 U 属性
1 | type Exclude<T, U> = T extends U ? never : T; |
Extract<T, U>
Exclude 的反操作,取 T,U 两者的交集属性
1 | type Extract<T, U> = T extends U ? T : never; |
NonNullable
排除类型 T 的 null | undefined 属性
1 | type NonNullable<T> = T extends null | undefined ? never : T; |
unknown、never 推导
unknown
1 | // T是任意类型,除了any |
never
never 类型是 unknown 的子类型
1 | // T是任意类型 |
TypeScript 中的问号 ? 与感叹号 !
问号 ?
1 | // 这里 Error对象定义的stack是可选参数,如果这样写的话编译器会提示 |
感叹号 !
1 | // 因为接口B里面name被定义为可空的值,但是实际情况是不为空的,那么我们就可以 |
参考文档: