keyof

keyof 与 Object.keys略有相似,keyof 是取 interface 的键,而 keyof 取到键后会保存为联合类型。

  1. interface iUserInfo{
  2. name: string;
  3. age: number;
  4. }
  5. type keys = keyof iUserInfo;

使用场景

  1. function getValue(o: object, key: string) {
  2. return o[key];
  3. }
  4. const obj1 = { name: '张三', age: 18 };
  5. const name = getValue(obj1, 'name');
  1. function getValue<T extends Object, K extends keyof T>(o: T, key: K): T[K] {
  2. return o[key];
  3. }
  4. const obj1 = { name: '张三', age: 18 };
  5. const a = getValue(obj1, 'name');

in

in用于取联合类型的值。主要用于数组和对象的构造。不能用于 interface。

  1. type name = 'firstName' | 'lastName';
  2. type TName = {
  3. [key in name]: string;
  4. };

infer实例

typescript不能不掌握的高级特性(二)
使用 infer 获取函数参数 Parameters
定义了一个函数类型 TArea,现在要实现将函数的参数类型取出来,我们该怎么做呢?

  1. type TArea = (width: number, height: number) => number;
  2. type params = Parameters<TArea>;
  3. // Parameters 是ts内置的方法

使用 infer 获取函数返回值 ReturnType

  1. type ReturnType<T extends (...args: any) => any> = T extends (
  2. ...args: any
  3. ) => infer R
  4. ? R
  5. : any;

获取实例类型 InstanceType

  1. type InstanceType<T extends new (...args: any) => any> = T extends new (
  2. ...args: any
  3. ) => infer R
  4. ? R
  5. : any;

获取构造函数类型 ConstructorParameters

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

获取参数 this 参数 ThisParameterType

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

剔除 this 参数 OmitThisParameter

Partial

Partial 将属性变为可选属性。举个栗子,iUser 这个接口 name 和 age 是必须的,但是同时又有另一个接口 iOptionUser,接口属性完全一样,只是里面的 name 和 age 是可选的

实现

  1. type Partial<T> = {
  2. [P in keyof T]?: T[P];
  3. };

场景

  1. interface iUser {
  2. name: string;
  3. age: number;
  4. }
  5. interface iOptionUser {
  6. name?: string;
  7. age?: number;
  8. }
  9. type iOptionUser = Partial<iUser>

Required

Required和Partial方法正好相反,是将属性变成必须。方法同样非常简单,可以这样实现(该方法已内置)

实现

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

场景

  1. interface iOptionUser {
  2. name?: string;
  3. age?: number;
  4. }
  5. type iUser = Required<iOptionUser>

Readonly

Readonly是将属性变成只读。方法同样非常简单,可以这样实现(该方法已内置)

  1. type Readonly<T> = {
  2. readonly [P in keyof T]: T[P];
  3. };
  1. interface iOptionUser {
  2. name?: string;
  3. age?: number;
  4. }
  5. type user = Readonly<iOptionUser>

Pick

Pick顾名思义,就是把一些属性挑选出来。效果如下:

源码

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

适用场景

  1. interface iDog {
  2. name: string,
  3. age: number;
  4. bark: () => void
  5. }
  6. type animal = Pick<iDog, "name" | "age">;

Record

Record用于创建一个具有同类型属性值的对象。

源码

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

Exclude

从类型 T 中剔除所有可以赋值给 U 的属性,然后构造一个类型。主要用于联合类型。

源码

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

场景

  1. type excludeA = Exclude<'a' | "b" | "c", "a">

Extract

功能与 Exclude相反

源码

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

场景

  1. type extractA = Extract<'a' | "b" | "c", "a">

Omit

主要用于剔除interface中的部分属性。 比如接口iUser包含name、age、firstName、lastName、location属性,而接口iUser2不包含location属性,我们可以使用前面提到的Pick实现,但这样会比较复杂,所以有了Omit 操作符。

  1. interface iUser {
  2. name: string;
  3. age: number;
  4. firstName: string;
  5. lastName: string;
  6. location: string;
  7. }
  8. /*interface iUser2 {
  9. name: string;
  10. age: number;
  11. firstName: string;
  12. lastName: string;
  13. }*/
  14. type iUser2 = Omit<iUser, "firstName">

链接