实现内置工具类型
Partial - 将类型T的所有属性改为可选
type Test1 = {
data: 1;
list: [];
info?: {};
num: number;
str?: string;
};
type T1 = Partial<Test1>;
实现部分
- 接受一个类型参数
- 使用in和keyof遍历这个参数上的所有key
- 将所有属性添加?变为可选
type MyPartial<T> = {
[K in keyof T]?: T[K];
};
type T2 = Partial<Test1>;
Required - 将类型T所有属性设为require必选
type Test1 = {
data: 1;
list: [];
info?: {};
num: number;
str?: string;
};
type T1 = Required<Test1>;
实现部分 (和Partia反着来就行)
- 接受一个类型参数
- 使用in和keyof遍历这个参数上的所有key
- 使用-?来删除属性上的?然后就变为必选
type MyRequired<T> = {
[K in keyof T]: T[K];
};
type T4 = MyRequired<Test1>;
Record - 构造一个类型,其属性名为K,属性值为V
type T5 = Record<1 | 2 | 3, string |number>;
实现部分
- 接受两个类型参数,一个是属性T,一个是值V
- 使用in遍历K,值取V即可
type MyRecord<T extends keyof any, V> = {
[K in T]: V;
};
type T6 = MyRecord<1 | 2 | 3, string |number>;
Pick - 从类型T中挑选部分属性K来构造新的类型
type Test1 = {
data: 1;
list: [];
info?: {};
num: number;
str?: string;
};
type T7 = Pick<Test1, "data" | "num">;
实现部分
- 接受两个类型参数,一个是属性T,一个是值K
- 使用in遍历K,这样就只取了传入的属性做新类型
- 值取T上的值,返回类型。
type MyPick<T, K extends keyof T> = {
[P in K]: T[P];
};
type T8 = MyPick<Test1, "data">;
Exclude - 从类型T中,剔除所有能赋值给U的属性
type T9 = Exclude<"string" | "number", "string">;
实现部分
联合类型使用extends时会触发分发,就是每一个元素单独比较
- 接受两个类型参数,一个是属性T,一个是值K
- 判断T是否满足K,满足的话返回never代表删除
type MyExclude<T, K> = T extends K ? never : T;
type T10 = MyExclude<"string" | "number", "string">;
Extract - 从类型T中提取所有可以赋值给S的类型
type T11 = Extract<"string" | "number", "string">;
实现部分 (与Exclude相反)
- 接受两个类型参数,一个是属性T,一个是值K
- 判断T是否满足K,满足的话返回这个T,不满足返回never代表删除
type MyExtract<T, K> = T extends K ? T : never;
type T12 = MyExtract<"string" | "number", "string">;
Omit - 从类型T中剔除所有能赋值给K的属性
与Exclude的区别在于Omit删除的是对象,Exclude删除的是联合类型
type Test1 = {
data: 1;
list: [];
info?: {};
num: number;
str?: string;
};
type T1 = Omit<Test1, "data">;
实现部分
- 接受两个类型参数,一个是属性T,一个是值K
- 使用Pick与Exclude这两个类型配合使用,
- Exclude先拿到从T类型删除后的联合类型
- Pick将原类型和Exclude删除完剩下的类型组成新类型
type Test1 = {
data: 1;
list: [];
info?: {};
num: number;
str?: string;
};
type MyOmit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>;
type T13 = MyOmit<Test1, "data">;
NonNullable - 从T中剔除null和undefined
type T1 = NonNullable - <"1" | "2" | 3 | 4 | null | undefined>
实现部分
- 接受一个类型参数
- T extends触发分发
- 判断T是否满足null与undefined
- 满足条件返回never则删除,其余正常返回
type MyNoNullable<T> = T extends null | undefined ? never : T;
type T14 = MyNoNullable<"1" | "2" | 3 | 4 | null | undefined>;
ReturnType - 获得函数返回值的类型
type T1 = ReturnType<()=>'test'>
实现部分
- 接受一个类型参数
- T通过模式匹配来判断是否满足一个函数
- 使用infer关键字取出返回值并返回
type T1 = ReturnType<()=>'test'>
type MyReturnType<T extends Function> = T extends (...args: any) => infer R
? R
: never;
type T15 = MyReturnType<() => 66>;
Readonly - 将T中所有属性设为只读
type Test1 = {
data: 1;
list: [];
info?: {};
num: number;
str?: string;
};
type T1 = Readonly<Test1>
实现部分
- 接受一个类型参数
- in与keyof配合进行遍历
- 在每个属性上面加上readonly即可
type MyRedoly<T> = {
readonly [K in keyof T]: T[K];
};
type T16 = MyRedoly<Test1>;
Parameters - 获取函数的参数args
type T1 = Parameters<(a: 1, b: 2) => {}>
实现部分 (与ReturnType相似,不过这次提取的是args)
- 接受一个类型参数
- T通过模式匹配来判断是否满足一个函数
- 使用infer关键字取出函数参数后返回
type MyParameters<T extends (...args: any) => any> = T extends (
...args: infer A
) => any
? A
: never;
type T17 = MyParameters<(a: 1, b: 2) => {}>;
ConstructorParameters - 构造函数的参数
type T1 = ConstructorParameters<new (a: 1) => 1>;
实现部分 (与函数的相似,只是多了个new)
- 接受一个类型参数
- T通过模式匹配来判断是否满足一个构造函数
- 使用infer关键字取出函数参数后返回
type MyConstructorParameters<T extends new (...args: any) => any> =
T extends new (...args: infer A) => any ? A : never;
type T18 = MyConstructorParameters<new (a: 1) => 1>;
InstanceType - 构造函数的返回值
type T1 = ConstructorParameters<new (a: 1) => 1>;
实现部分 (与函数的相似,只是多了个new)
- 接受一个类型参数
- T通过模式匹配来判断是否满足一个构造函数
- 使用infer关键字取出构造函数返回值后返回
type MyInstanceType<T extends new (...args: any) => any> = T extends new (
...args: any
) => infer R
? R
: any;
type T19 = MyInstanceType<new () => 999>;