Partial

Partial 作用是将传入的属性变为可选项.
keyof: 用来取得一个对象接口的所有 key值.

  1. interface Foo {
  2. name: string;
  3. age: number
  4. }
  5. type T = keyof Foo // -> "name" | "age"

in: 可以遍历枚举类型

  1. type Keys = "a" | "b"
  2. type Obj = {
  3. [p in Keys]: any
  4. } // -> { a: any, b: any }

keyof 产生枚举类型, in 使用枚举类型遍历, 所以他们经常一起使用, 看下 Partial 源码

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

上面语句的意思是 keyof T 拿到 T 所有属性名, 然后 in 进行遍历, 将值赋给 P, 最后 T[P] 取得相应属性的值.
结合中间的 ? 我们就明白了 Partial 的含义了.

Required

Required 的作用是将传入的属性变为必选项, 源码如下

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

-?这里很好理解,就是将可选项代表的 ? 去掉, 从而让这个类型变成必选项. 与之对应的还有个+? , 这个含义自然与-?之前相反, 它是用来把属性变成可选项的.

Mutable

将 T 的所有属性的 readonly 移除.

  1. type Mutable<T> = {
  2. -readonly [P in keyof T]: T[P]
  3. }

Readonly

将传入的属性变为只读选项, 源码如下

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

Record

将 K 中所有的属性的值转化为 T 类型

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

Pick

从 T 中取出 一系列 K 的属性

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

Exclude

首先介绍一下条件类型:
如果 T 是 U 的子类型的话,那么就会返回 X,否则返回 Y

  1. T extends U ? X : Y

甚至可以组合多个

  1. type TypeName<T> =
  2. T extends string ? "string" :
  3. T extends number ? "number" :
  4. T extends boolean ? "boolean" :
  5. T extends undefined ? "undefined" :
  6. T extends Function ? "function" :
  7. "object";

对于联合类型来说会自动分发条件,例如 T extends U ? X : Y, T 可能是 A | B 的联合类型, 那实际情况就变成(A extends U ? X : Y) | (B extends U ? X : Y)

Exclude源码:
从 T 中找出 U 中没有的元素, 换种更加贴近语义的说法其实就是从T 中排除 U

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

例如:

  1. type T = Exclude<1 | 2, 1 | 3> // -> 2

Extract

提取出 T 包含在 U 中的元素, 换种更加贴近语义的说法就是从 T 中提取出 U.

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

Omit

用之前的 Pick 和 Exclude 进行组合, 实现忽略对象某些属性功能.

  1. type Omit = Pick<T, Exclude<keyof T, K>>

例如:

  1. type Foo = Omit<{name: string, age: number}, 'name'> // -> { age: number }

ReturnType

首先介绍一下infer关键字。我们可以用 infer 声明一个类型变量并且对它进行使用。
例如,获取函数的返回类型:

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

这里的 infer R 就是声明一个变量来承载传入函数签名的返回值类型, 简单说就是用它取到函数返回值的类型方便之后使用.

ReturnType用法:

  1. function foo(x: number): Array<number> {
  2. return [x];
  3. }
  4. type fn = ReturnType<typeof foo>;

AxiosReturnType

开发经常使用 axios 进行封装 API层 请求, 通常是一个函数返回一个 AxiosPromise<Resp>, 现在我想取到它的 Resp 类型, 根据上一个工具泛型的知识我们可以这样写.

  1. import { AxiosPromise } from 'axios' // 导入接口
  2. type AxiosReturnType<T> =
  3. T extends (...args: any[]) => AxiosPromise<infer R> ? R : any
  4. // 使用
  5. type Resp = AxiosReturnType<Api> // 泛型参数中传入你的 Api 请求函数