TypeScript 中常用的内置工具类型:
可选
的1.源码
type Partial = {
[P in keyof T]?: T[P];
}
2.使用
// 定义一个通用的 Person 类
interface Person {
name: string;
age?: number;
weight?: number;
}
type PartialPerson = Partial;
// 相当于
interface PartialPerson {
name?: string;
age?: number;
weight?: number;
}
必填
的(与 Partial 工具类型相反)1.源码:映射类型在键值的后面使用了一个 - 符号,- 与 ? 组合起来表示去除类型的可选属性
,因此给定类型的所有属性都变为了必填。
type Required = {
[P in keyof T]-?: T[P];
};
2.使用
type RequiredPerson = Required;
// 相当于
interface RequiredPerson {
name: string;
age: number;
weight: number;
}
只读
,这意味着属性不可以被重新赋值1.源码
type Readonly = {
readonly [P in keyof T]: T[P];
};
2.使用
type ReadonlyPerson = Readonly;
// 相当于
interface ReadonlyPerson {
readonly name: string;
readonly age?: number;
readonly weight?: number;
}
1.源码:Pick工具类型接收了两个泛型参数:第一个 T 为给定的参数类型,而第二个参数为需要提取的键值 key。有了参数类型和需要提取的键值 key,我们就可以通过映射类型很容易地实现 Pick 工具类型的功能。
type Pick = {
[P in K]: T[P];
};
2.使用
type NewPerson = Pick;
// 相当于
interface NewPerson {
name: string;
age?: number;
}
1.源码:
type Omit = Pick>;
2.使用
type NewPerson = Omit;
// 相当于
interface NewPerson {
name: string;
age?: number;
}
|
将变量设置多种类型)1.源码:从 T 中剔除可以赋值给 U 的类型,如果 T 是 U 的子类型,则返回 never 不是则返回 T
type Exclude = T extends U ? never : T
2.使用
type A = number | string | boolean
type B = number | boolean
type Foo = Exclude
// 相当于
type Foo = string
1.源码
type Extract = T extends U ? T : never;
2.使用
type A = number | string | boolean
type B = number | boolean
type Foo = Extract
// 相当于
type Foo = number | boolean
1.源码
type NonNullable = T extends null | undefined ? never : T;
2.使用
type T = NonNullable; // => string | number
1.源码:接收了两个泛型参数:第一个参数作为接口类型的属性,第二个参数作为接口类型的属性值。
type Record = {
[P in K]: T;
};
2.使用
type MenuKey = 'home' | 'about' | 'more';
interface Menu {
label: string;
hidden?: boolean;
}
const menus: Record = {
about: { label: '关于' },
home: { label: '主页' },
more: { label: '更多', hidden: true },
};
1.源码
type ConstructorParameters any> = T extends new (
...args: infer P
) => any
? P
: never;
2.使用
class Person {
constructor(name: string, age?: number) {}
}
type T = ConstructorParameters; // [name: string, age?: number]
1.源码:以元组的方式获得函数的入参类型
type Parameters any> = T extends (...args: infer P) => any ? P : never;
2.使用
type T0 = Parameters<() => void>; // []
type T1 = Parameters<(x: number, y?: string) => void>; // [x: number, y?: string]
type T2 = Parameters<(name: string) => any>; // type T2 = [string]
type T3= Parameters<((name: string) => any) | ((age: number) => any)>; // type T3= [string] | [number]
1.源码
type ReturnType any> = T extends (...args: any) => infer R ? R : any;
2.使用
type T0 = ReturnType<() => void>; // => void
type T1 = ReturnType<() => string>; // => string
1.源码
type ThisParameterType = T extends (this: infer U, ...args: any[]) => any ? U : unknown;
2.使用
type T = ThisParameterType<(this: Number, x: number) => void>; // Number
1.源码
type ObjectDescriptor = {
data?: D;
methods?: M & ThisType; // methods 中 this 的类型是 D & M
};
2.使用
function makeObject(desc: ObjectDescriptor): D & M {
let data: object = desc.data || {};
let methods: object = desc.methods || {};
return { ...data, ...methods } as D & M;
}
const obj = makeObject({
data: { x: 0, y: 0 },
methods: {
moveBy(dx: number, dy: number) {
this.x += dx; // this => D & M
this.y += dy; // this => D & M
},
},
});
obj.x = 10;
obj.y = 20;
obj.moveBy(5, 5);
1.源码
type OmitThisParameter = unknown extends ThisParameterType
? T
: T extends (...args: infer A) => infer R
? (...args: A) => R
: T;
2.使用
type T = OmitThisParameter<(this: Number, x: number) => string>; // (x: number) => string
1.源码
// 转换字符串字面量到大写字母
type Uppercase = intrinsic;
// 转换字符串字面量到小写字母
type Lowercase = intrinsic;
// 转换字符串字面量的第一个字母为大写字母
type Capitalize = intrinsic;
// 转换字符串字面量的第一个字母为小写字母
type Uncapitalize = intrinsic;
2.使用
type T0 = Uppercase<'Hello'>; // => 'HELLO'
type T1 = Lowercase; // => 'hello'
type T2 = Capitalize; // => 'Hello'
type T3 = Uncapitalize; // => 'hello'
TypeScript 官方工具类型
TS 里几个常用的内置工具类型(Record、Partial 、 Required 、 Readonly、 Pick 、 Exclude 、 Extract 、 Omit)的使用