TypeScript 工具泛型教程示例
作者:卡卡
这篇文章主要为大家介绍了TypeScript 工具泛型教程示例,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
前言
Typescript 中默认内置了很多工具泛型,通过使用这些工具,可以使得我们定义类型更加灵活,高效。本文将会介绍常用泛型工具的使用技巧,以及对其实现原理进行相应的解析,如果有错误的地方,还望指出。
Partial\<T>
作用:将传入对象类型 T 的属性变为可选属性。
示例:
interface Person {
name: string;
age: number;
}
const tom: Partial<Person> = {
name: "Tom",
};javascript:void(0)Partial<Person> 等价于
interface Person {
name?: string;
age?: number;
}实现原理:
- 通过关键字
keyof将传入对象类型的键值转换为联合类型。 - 通过关键字
in遍历联合类型,即遍历对象的键值。 - 通过类型映射,将对象的属性转换为可选属性
type MyPartial<T> = {
[P in keyof T]?: T[P];
};Readonly\<T>
作用:把传入对象类型 T 属性变为只读属性。
示例:
interface Person {
name: string;
age: number;
}
const tom: Readonly<Person> = {
name: "Tom",
age: 18;
};
tom.age = 22 // errorReadonly<Person> 等价于
interface Person {
readonly name: string;
readonly age: number;
}实现原理:
与Partial类似:
- 通过关键字
keyof将传入对象类型的键值转换为联合类型。 - 通过关键字
in遍历联合类型,即遍历对象的键值。 - 通过类型映射,将对象的属性转换为只读属性
type Readonly<T> = {
[P in keyof T]-?: T[P];
};Required\<T>
作用:把传入对象类型 T 属性变为必填属性。
示例:
interface Person {
name?: string;
age?: number;
}
let tom: Required<Person>
tom = {
name: "Tom",
age: 18;
};
// ok
tom = {
name: "Tom",
};
// error实现原理:
与Partial类似:
- 通过关键字
keyof将传入对象的键值转换为枚举类型。 - 通过关键字
in遍历枚举类型,即遍历对象的键值。 - 通过类型映射,再统一通过
-?修饰符移除?修饰符,从而转变为必填状态。
type Required<T> = {
Required [P in keyof T]: T[P];
};Record\<K,T>
作用:它用来生成一个属性名为 K,属性值类型为 T 的对象类型集合。
示例:
// 快速生成一个 Person 对象
type Person = Record<"name" | "country", string>;
const Tom: Person = { name: "Tom", country: "America" };实现原理:
- 通过
K extends keyof any对K参数进行约束,将其约束为任意类型any的键值。 - 通过
in对键值集合K进行遍历,然后生成类型为T的键值对集合。
type MyRecord<K extends keyof any, T> = {
[P in K]: T;
};Exclude\<T,K>
作用:从类型 T 中排除所有可以赋值给类型 U 的类型。
示例:
// 从 "a" | "b" | "c" 中排除掉 "a" 类型 type T1 = Exclude<"a" | "b" | "c", "a">; // T1 = "b" | "c" // 从 string | number | boolean 中排除掉 string 类型 type T2 = Exclude<string | number | boolean, string>; // T2 = number | boolean
实现原理:
通过条件类型
T extends U ? never : T对T参数进行判别:- 如果
T可赋值给U,那么返回never(即排除掉T)。 - 如果
T不可赋值给U,那么返回T。
- 如果
- 通过分布式条件类型,如果
T为联合类型,则将条件类型的结果分发为联合类型。
type Exclude<T, U> = T extends U ? never : T;
Extract\<T,K>
作用:与 Exclude 相反,从类型 T 中提取所有可以赋值给类型 U 的类型。
示例:
// 从 "a" | "b" | "c" 中提取出 "a" 类型 type T1 = Extract<"a" | "b" | "c", "a">; // T1 = "a" // 从 string | number | boolean 中提取出 string 类型 type T2 = Extract<string | number | boolean, string>; // T2 = string type T3 = Extract<string | (() => void), Function>; // 相当于 type T3 = () => void;
实现原理:
与 Exclude 类似:
通过条件类型
T extends U ? never : T对T参数进行判别:- 如果
T可赋值给U,那么返回T。 - 如果
T不可赋值给U,那么返回never(即排除掉T)。
- 如果
- 通过分布式条件类型,如果
T为联合类型,则将条件类型的结果分发为联合类型。
type Extract<T, U> = T extends U ? T : never;
Pick\<T,K>
作用:在 T 中,摘选出 K 属性。
示例:
interface Person {
name: string;
age: number;
}
// 从 Person 中摘选出 name 属性
type PickPerson = Pick<Person, "name">;
const tom: PickPerson = {
name: "Tom",
};实现原理:
- 通过
K extends keyof T对K参数进行约束,将其约束为T的键值范围内。 - 通过
in对键值集合K进行遍历,然后生成类型为T的键值对集合。
type Pick<T, K extends keyof T> = {
[P in K]: T[P];
};Omit\<T,K>
作用:在 T 中,剔除掉 K 属性。
示例:
interface Person {
name: string;
age: number;
}
// 从 Person 中剔除掉 name 属性
type OmitPerson = Omit<Person, "name">;
const tom: OmitPerson = {
age: 18,
};实现原理:
- 通过
K extends keyof T对K参数进行约束,将其约束为T的键值范围内。 - 通过
Exclude<keyof T, K>将类型集合T中的K类型排除掉。 - 通过
Pick<T,Exclude<keyof T, K>>在T中摘选出排除掉K的T的属性。
type Omit<T, K extends keyof any> = Pick<T, Exclude<keyof T, K>>;
ReturnType\<T>
作用:获取函数的返回值类型。
示例:
type Fun = () => string;
// 获取 Fun 返回值的类型
type T1 = ReturnType<Fun>; // T1 = string
type T2 = ReturnType<() => { x: number; y: number }>;
// T2 = { x: number, y: number }实现原理:
- 通过
extends对T参数进行约束,(...args: any) => any表示一个函数类型,即T参数的类型必须是一个函数类型。 T extends U ? X : Y是条件类型(注意和之前表示约束的extends做区分),其中T是泛型参数,U是条件部分,X是符合条件的返回结果,Y是不符合条件的返回结果。- 推断类型
infer的作用是:在条件类型内部声明一个类型变量。(...args: any) => infer R是条件类型的条件部分,它声明了一个类型变量R,用来存储函数的返回类型。 T extends (...args: any) => any> = T extends (...args: any) => infer R ? R : any表示:- 如果
T是函数类型((...args: any) => infer R),则返回R, 即函数的返回类型。 - 如果
T不是函数类型((...args: any) => infer R),则返回any。
- 如果
type ReturnType<T extends (...args: any) => any> = T extends ( ...args: any ) => infer R ? R : any;
参考资料
以上就是TypeScript 工具泛型教程示例的详细内容,更多关于TypeScript 工具泛型的资料请关注脚本之家其它相关文章!
