泛型编程(下)
介绍一些 TS 内置工具类型的用法及实现
Readonly & Mutable
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| type Person = { id: number; name: string; age: number };
type Readonly<T> = { readonly [K in keyof T]: T[K]; }; type X1 = Readonly<Person>;
type Mutable<T> = { -readonly [K in keyof T]: T[K]; }; type X9 = Mutable<Readonly<Person>>;
|
注意:
Mutable
并不是 TS 内置的函数
-readonly []
表示去掉属性前面的 Readonly
Partial & Required
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| type Person = { id: number; name: string; age: number };
type Partial<T> = { [K in keyof T]?: T[K]; }; type X2 = Partial<Person>;
type Required<T> = { [K in keyof T]-?: T[K]; }; type X3 = Required<Person>;
|
注意 -?
,表示去掉属性的可选,变为必选
1 2 3 4 5
| type Exclude<A, B> = A extends B ? never : A; type X5 = Exclude<1 | 2 | 3, 1 | 2>;
type Extract<A, B> = A extends B ? A : never; type X6 = Extract<1 | 2 | 3, 2 | 4>;
|
按照之前讲的乘法分配律,有如下理解过程:
1 2 3 4 5 6 7 8
| type X5 = 1 | 2 | 3 extends 1 | 2 ? never : A
type X5 = | 1 extends 1 | 2 ? never : 1 | 2 extends 1 | 2 ? never : 2 | 3 extends 1 | 2 ? never : 3
type X5 = never | never | 3
|
X6
的理解过程同 X5
,这里不赘述
Omit & Pick
1 2 3 4 5 6 7 8 9 10 11 12 13
| type Person = { id: number; name: string; age: number };
type Omit<T, Key extends keyof T> = Pick<T, Exclude<keyof T, Key>>;
type Omit<T, Key> = { [K2 in keyof T as (K2 extends Key ? never : K2)]: T[K2]; }; type X7 = Omit<Person, 'name' | 'age'>;
type Pick<T, Key extends keyof T> = { [K2 in Key]: T[K2]; }; type X8 = Pick<Person, 'name' | 'age'>;
|
Key extends keyof T
是一个泛型约束,约束所传的 key
必须包含在 keyof T
中,即必须是 'id' | 'name' | 'age'
的子集
Record
1 2 3 4 5
| type Record<Key extends string | number | symbol, Value> = { [k in Key]: Value; };
type X4 = Record<string, string>;
|
ReturnType
1 2 3 4 5
| function f(a: number, b: number) { return 'a + b' }
type F = ReturnType<typeof f>
|
其他
这里推荐一个用于练习 TS 类型体操的 repo:TypeScript 类型体操姿势合集
看看别人的体操: