一、类型工具
TypeScript 提供了一些内置的类型工具,用来方便地处理各种类型,以及生成新的类型。
Exclude<T, U>
从 T
中排除出可分配给 U
的元素。
Omit<T, K>
的作用是忽略T
中的某些属性。
Merge<O1, O2>
是将两个对象的属性合并。
Compute<A & B>
是将交叉类型合并
Intersection<T, U>
的作用是取T
的属性,此属性同样也存在与U
。
Overwrite<T, U>
是用U
的属性覆盖T
的相同属性。
Pick<Type, Keys>
Pick<Type, Keys>
返回一个新的对象类型,第一个参数Type
是一个对象类型,第二个参数Keys
是Type
里面被选定的键名。
1 | interface A { |
上面示例中,Pick<Type, Keys>
会从对象类型A
里面挑出指定的键名,组成一个新的对象类型。
指定的键名Keys
必须是对象键名Type
里面已经存在的键名,否则会报错。
1 | interface A { |
上面示例中,对象类型A
不存在键名z
,所以报错了。
Pick<Type, Keys>
的实现如下。
1 | type Pick<T, K extends keyof T> = { |
Omit<Type, Keys>
Omit<Type, Keys>
用来从对象类型Type
中,删除指定的属性Keys
,组成一个新的对象类型返回。
1 | interface A { |
上面示例中,Omit<Type, Keys>
从对象类型A
里面删除指定属性,返回剩下的属性。
指定删除的键名Keys
可以是对象类型Type
中不存在的属性,但必须兼容string|number|symbol
。
1 | interface A { |
上面示例中,对象类型A
中不存在属性z
,所以就原样返回了。
Omit<Type, Keys>
的实现如下。
1 | type Omit<T, K extends keyof any> |
Exclude<UnionType, ExcludedMembers>
Exclude<UnionType, ExcludedMembers>
用来从联合类型UnionType
里面,删除某些类型ExcludedMembers
,组成一个新的类型返回。
1 | type T1 = Exclude<'a'|'b'|'c', 'a'>; // 'b'|'c' |
Exclude<UnionType, ExcludedMembers>
的实现如下。
1 | type Exclude<T, U> = T extends U ? never : T; |
上面代码中,等号右边的部分,表示先判断T
是否兼容U
,如果是的就返回never
类型,否则返回当前类型T
。由于never
类型是任何其他类型的子类型,它跟其他类型组成联合类型时,可以直接将never
类型从联合类型中“消掉”,因此Exclude<T, U>
就相当于删除兼容的类型,剩下不兼容的类型。
Extract<Type, Union>
Extract<UnionType, Union>
用来从联合类型UnionType
之中,提取指定类型Union
,组成一个新类型返回。它与Exclude<T, U>
正好相反。
1 | type T1 = Extract<'a'|'b'|'c', 'a'>; // 'a' |
如果参数类型Union
不包含在联合类型UnionType
之中,则返回never
类型。
1 | type T = Extract<string|number, boolean>; // never |
Extract<UnionType, Union>
的实现如下。
1 | type Extract<T, U> = T extends U ? T : never; |
Partial<Type>
Partial<Type>
返回一个新类型,将参数类型Type
的所有属性变为可选属性。
1 | interface A { |
Partial<Type>
的实现如下。
1 | type Partial<T> = { |
Readonly<Type>
Readonly<Type>
返回一个新类型,将参数类型Type
的所有属性变为只读属性。
1 | interface Todo { |
Required<Type>
Required<Type>
返回一个新类型,将参数类型Type
的所有属性变为必选属性。它与Partial<Type>
的作用正好相反。
1 | interface A { |
Required<Type>
的实现如下。
1 | type Required<T> = { |
上面代码中,符号-?
表示去除可选属性的“问号”,使其变成必选属性。
相对应地,符号+?
表示增加可选属性的“问号”,等同于?
。因此,前面的Partial<Type>
的定义也可以写成下面这样。
1 | type Partial<T> = { |
Record<Keys, Type>
构造一个类型,它的所有key是Keys类型,所有value是Type类型
1 | interface Employee { |