深入浅出TS常见工具类型

386 阅读3分钟

介绍ts工具类型、使用场景以及模拟实现。

Partial<T>

1. 含义: 构造一个新类型,把类型T中的所有属性转化为可选属性

2. 示例:

	interface A {
		x: number ;
		y: number;
	}

type T = Partial<A>  // {x?: numner; y?:number}

3. 模拟实现

type myPartial<T> = {
	[key in keyof T]?: T[key]
}

Required<T>

1. 含义: 构造一个新类型,把类型T中的所有属性转化为必选属性

2. 示例:

	interface A {
		x: number ;
		y: number;
	}

type T = Required<A>  // {x: numner; y:number}

3. 模拟实现

需要通过-?将类型变成必选的

type myRequired<T> = {
	[key in keyof T]-?: T[key]
}

Readonly<T>

1. 含义: 构造一个新类型,把类型T中的所有属性转化为只读属性

2. 示例:

	interface A {
		x: number ;
		y: number;
	}

type T = Readonly<A>  // { readonly x: number; readonly y:number}

const a: T = { x:0, y:0 }
a.x = 1; // 编译错误!不允许修改

3. 模拟实现

type myReadonly<T> = {
	readonly [key in keyof T]: T[key]
}

Pick<T,U>

1. 含义: 从已有类型对象中挑选出给定的属性和类型

2. 示例:

	interface A {
		x: number ;
		y: number;
		z: number;
	}

type T0 = Pick<A,'x'|'y'>  // { x: number; y :number; }
type T1 = Pick<A,'x'>  // { x: number; }


3. 模拟实现

这里再实现上需要注意的是,因为要从T中挑选U,所以U一定是T的键值的子集,这个地方要对U这个泛型做限制。

3.1 使用对象类型来表示

type myPick<T,U extends keyof T> = {
	[key in U]:T[key]
}

3.2 函数字面量来表示

type myPick = <T,U extends keyof T> (obj :T, keys: U[]) =>  { [key in U]:T[key] }

Omit<T,U>

1. 含义: 从类型 T 中排除一组属性 K,并创建一个新类型。

2. 示例:

interface Person {
  name: string;
  age: number;
  address: string;
}

type PersonWithoutAddress = Omit<Person, "address">; // { name: string; age: number; }


3. 模拟实现

可以通过Pick挑选出除了(Exclude)U中的属性,返回新类型。这里要注意Exclude第一项是 keyof T,而不是T。

type myOmit<T,U extends T> = myPick<T,Exclude<keyof T,U>>

Record<K,T>

1. 含义: 给出K(一组Key),类型T,返回新类型,一组Key类型都是T

2. 示例:

type StatusCodeDescriptions = Record<200 | 404 | 500, string>;

const statusDescriptions: StatusCodeDescriptions = {
  200: "OK",
  404: "Not Found",
  500: "Internal Server Error",
};


3. 模拟实现

这里要注意的是对K的类型限制K extends keyof any

type myRecord<K extends keyof any,T> = {
	[key in K]: T
}

Exclude<T,U>

1. 含义: 从类型T中排除可以分配给类型U的属性

2. 示例:

type NonNullableValues = Exclude<string | number | null | undefined, null | undefined>; // string | number

3. 模拟实现

type myExclude = T extends U ? never : T;

ReturnType<T>

1. 含义: 获取函数类型T的返回类型

2. 示例:


function greet(name: string): string {
  return `Hello, ${name}`;
}

type Greeting = ReturnType<typeof greet>; // string


3. 模拟实现

returnType需要通过使用infer关键字(infer占位结合条件类型做类型推断)结合extends来实现

infer 是 TypeScript 中的类型推断关键字,通常与条件类型一起使用。在条件类型中,我们可以使用 infer 关键字在一个类型推断位置上声明一个类型变量。然后在条件类型的真分支中,我们可以引用这个类型变量这使得 TypeScript 能够在条件类型的上下文中推断一个类型。

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

InstanceType<T>

1. 含义: 获取构造函数T的返回类型

2. 示例:


class Person {
  constructor(public name: string, public age: number) {}
}

type PersonInstance = InstanceType<typeof Person>; // Person


3. 模拟实现

type myInstanceType<T extends new (...args: any[]) => any> = T extends new (...args: any[]) => infer R ? R : any;

NonNullable<T>

1. 含义

过滤掉Null、undefiened类型

2. 模拟实现

type NonNullable = T & {}