> 文章列表 > TypeScript 中常用的内置工具类型

TypeScript 中常用的内置工具类型

TypeScript 中常用的内置工具类型

TypeScript 中常用的内置工具类型

一:操作接口类型

1. Partial:可以将类型的所有属性都变为可选

1.源码

type Partial<T> = {[P in keyof T]?: T[P];
}
  • keyof T:通过类型索引 keyof 的得到联合类型 ‘name’ | ‘age’ | ‘weight’
  • P in keyof T 等同于 p in ‘name’ | ‘age’ | ‘weight’,相当于执行了一次 forEach 的逻辑,遍历 ‘name’ | ‘age’ | ‘weight’

2.使用

// 定义一个通用的 Person 类
interface Person {name: string;age?: number;weight?: number;
}
type PartialPerson = Partial<Person>;// 相当于
interface PartialPerson {name?: string;age?: number;weight?: number;
}

2. Required:可以将类型的所有属性都变为必填的(与 Partial 工具类型相反)

1.源码:映射类型在键值的后面使用了一个 - 符号,- 与 ? 组合起来表示去除类型的可选属性,因此给定类型的所有属性都变为了必填。

type Required<T> = {[P in keyof T]-?: T[P];
};

2.使用

type RequiredPerson = Required<Person>;// 相当于
interface RequiredPerson {name: string;age: number;weight: number;
}

3.Readonly:可以将类型的所有属性设为只读,这意味着属性不可以被重新赋值

1.源码

type Readonly<T> = {readonly [P in keyof T]: T[P];
};

2.使用

type ReadonlyPerson = Readonly<Person>;// 相当于
interface ReadonlyPerson {readonly name: string;readonly age?: number;readonly weight?: number;
}

4.Pick:可以从类型中选取出指定的键值,然后组成一个新的类型

1.源码:Pick工具类型接收了两个泛型参数:第一个 T 为给定的参数类型,而第二个参数为需要提取的键值 key。有了参数类型和需要提取的键值 key,我们就可以通过映射类型很容易地实现 Pick 工具类型的功能。

type Pick<T, K extends keyof T> = {[P in K]: T[P];
};

2.使用

type NewPerson = Pick<Person, 'name' | 'age'>;// 相当于
interface NewPerson {name: string;age?: number;
}

5.Omit:返回去除指定的键值之后返回的新类型(与 Pick 类型相反)

1.源码:

type Omit<T, K extends keyof any> = Pick<T, Exclude<keyof T, K>>;

2.使用

type NewPerson = Omit<Person, 'weight'>;// 相当于
interface NewPerson {name: string;age?: number;
}

二:联合类型(可以通过|将变量设置多种类型)

6.Exclude:从联合类型中去除指定的类型

1.源码:从 T 中剔除可以赋值给 U 的类型,如果 T 是 U 的子类型,则返回 never 不是则返回 T

type Exclude<T, U> = T extends U ? never : T

2.使用

type A = number | string | boolean
type B = number | booleantype Foo = Exclude<A, B>// 相当于
type Foo = string

7.Extract:从联合类型中提取指定的类型,类似于操作接口类型中的 Pick 类型(和Exclude相反)

1.源码

type Extract<T, U> = T extends U ? T : never;

2.使用

type A = number | string | boolean
type B = number | booleantype Foo = Extract<A, B>// 相当于
type Foo = number | boolean

8.NonNullable:从联合类型中去除 null 或者 undefined 的类型

1.源码

type NonNullable<T> = T extends null | undefined ? never : T;

2.使用

type T = NonNullable<string | number | undefined | null>; // => string | number

9.Record:生成接口类型,然后我们使用传入的泛型参数分别作为接口类型的属性和值

1.源码:接收了两个泛型参数:第一个参数作为接口类型的属性,第二个参数作为接口类型的属性值。

type Record<K extends keyof any, T> = {[P in K]: T;
};

2.使用

type MenuKey = 'home' | 'about' | 'more';
interface Menu {label: string;hidden?: boolean;
}
const menus: Record<MenuKey, Menu> = {about: { label: '关于' },home: { label: '主页' },more: { label: '更多', hidden: true },
};

三:函数类型

10.ConstructorParameters:可以用来获取构造函数的构造参数,而 ConstructorParameters 类型的实现则需要使用 infer 关键字推断构造参数的类型。

1.源码

type ConstructorParameters<T extends new (...args: any) => any> = T extends new (...args: infer P
) => any? P: never;

2.使用

class Person {constructor(name: string, age?: number) {}
}
type T = ConstructorParameters<typeof Person>; // [name: string, age?: number]

11.Parameters:可以用来获取函数的参数并返回序对

1.源码:以元组的方式获得函数的入参类型

type Parameters<T extends (...args: any) => 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]

12.ReturnType:用来获取函数的返回类型

1.源码

type ReturnType<T extends (...args: any) => any> = T extends (...args: any) => infer R ? R : any;

2.使用

type T0 = ReturnType<() => void>; // => void
type T1 = ReturnType<() => string>; // => string

13.ThisParameterType:用来获取函数的 this 参数类型

1.源码

type ThisParameterType<T> = T extends (this: infer U, ...args: any[]) => any ? U : unknown;

2.使用

type T = ThisParameterType<(this: Number, x: number) => void>; // Number

14.ThisType:可以在对象字面量中指定 this 的类型

1.源码

type ObjectDescriptor<D, M> = {data?: D;methods?: M & ThisType<D & M>; // methods 中 this 的类型是 D & M
};

2.使用

function makeObject<D, M>(desc: ObjectDescriptor<D, M>): 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 & Mthis.y += dy; // this => D & M},},
});
obj.x = 10;
obj.y = 20;
obj.moveBy(5, 5);

15.OmitThisParameter:用来去除函数类型中的 this 类型

1.源码

type OmitThisParameter<T> = unknown extends ThisParameterType<T>? T: T extends (...args: infer A) => infer R? (...args: A) => R: T;

2.使用

type T = OmitThisParameter<(this: Number, x: number) => string>; // (x: number) => string

四:字符串类型

16. Uppercase、Lowercase、Capitalize、Uncapitalize

1.源码

// 转换字符串字面量到大写字母
type Uppercase<S extends string> = intrinsic;
// 转换字符串字面量到小写字母
type Lowercase<S extends string> = intrinsic;
// 转换字符串字面量的第一个字母为大写字母
type Capitalize<S extends string> = intrinsic;
// 转换字符串字面量的第一个字母为小写字母
type Uncapitalize<S extends string> = intrinsic;

2.使用

type T0 = Uppercase<'Hello'>; // => 'HELLO'
type T1 = Lowercase<T0>; // => 'hello'
type T2 = Capitalize<T1>; // => 'Hello'
type T3 = Uncapitalize<T2>; // => 'hello'

TypeScript 官方工具类型
TS 里几个常用的内置工具类型(Record、Partial 、 Required 、 Readonly、 Pick 、 Exclude 、 Extract 、 Omit)的使用

数豆子字体