Partial

Partial 作用是将传入的属性变为可选项.首先我们需要理解两个关键字keyof和in,keyof可以用来取得一个对象接口的所有key值.比如
interface Foo {
name: string;
age: number
}
type T = keyof Foo _// -> “name” | “age”


而 in 则可以遍历枚举类型, 例如
type Keys = “a” | “b”
type Obj = {
[p in Keys]: any
}
// -> { a: any, b: any }

_
keyof产生联合类型,in则可以遍历枚举类型, 所以他们经常一起使用, 看下 Partial 源码
type Partial = { [P in keyof T]?: T[P] };

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

Required

Required 的作用是将传入的属性变为必选项, 源码如下
type Required = { [P in keyof T]-?: T[P] };

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

Mutable (未包含)

类似地, 其实还有对+和-, 这里要说的不是变量的之间的进行加减而是对readonly进行加减.以下代码的作用就是将 T 的所有属性的 readonly 移除,你也可以写一个相反的出来.
type Mutable = {
-readonly [P in keyof T]: T[P]
}

Readonly

将传入的属性变为只读选项, 源码如下
type Readonly = { readonly [P in keyof T]: T[P] };

Record

将 K 中所有的属性的值转化为 T 类型
type Record = { [P in K]: T };

Pick

从 T 中取出 一系列 K 的属性
type Pick = { [P in K]: T[P] };

Exclude

在 ts 2.8 中引入了一个条件类型, 示例如下
T extends U ? X : Y

以上语句的意思就是 如果 T 是 U 的子类型的话,那么就会返回 X,否则返回 Y
甚至可以组合多个
type TypeName =
T extends string ? “string” :
T extends number ? “number” :
T extends boolean ? “boolean” :
T extends undefined ? “undefined” :
T extends Function ? “function” :
“object”;

对于联合类型来说会自动分发条件,例如T extends U ? X : Y, T 可能是A | B的联合类型, 那实际情况就变成(A extends U ? X : Y) | (B extends U ? X : Y)
有了以上的了解我们再来理解下面的工具泛型
来看看 Exclude 源码
type Exclude = T extends U ? never : T;

结合实例
type T = Exclude<1 | 2, 1 | 3> _// -> 2

_
很轻松地得出结果2根据代码和示例我们可以推断出 Exclude 的作用是从 T 中找出 U 中没有的元素, 换种更加贴近语义的说法其实就是从T 中排除 U

Extract

根据源码我们推断出 Extract 的作用是提取出 T 包含在 U 中的元素, 换种更加贴近语义的说法就是从 T 中提取出 U源码如下
type Extract = T extends U ? T : never;

Omit (未包含)

用之前的 Pick 和 Exclude 进行组合, 实现忽略对象某些属性功能, 源码如下
type Omit = Pick>

// 使用
type Foo = Omit<{name: string, age: number}, ‘name’> _// -> { age: number }

_

ReturnType

在阅读源码之前我们需要了解一下infer这个关键字, 在条件类型语句中, 我们可以用infer声明一个类型变量并且对它进行使用,我们可以用它获取函数的返回类型, 源码如下
type ReturnType = T extends (
…args: any[]
) => infer R
? R
: any;

其实这里的infer R就是声明一个变量来承载传入函数签名的返回值类型, 简单说就是用它取到函数返回值的类型方便之后使用.具体用法
function foo(x: number): Array {
return [x];
}
type fn = ReturnType;

AxiosReturnType (未包含)

开发经常使用 axios 进行封装 API层 请求, 通常是一个函数返回一个AxiosPromise, 现在我想取到它的 Resp 类型, 根据上一个工具泛型的知识我们可以这样写.
import { AxiosPromise } from ‘axios’ // 导入接口
type AxiosReturnType = T extends (…args: any[]) => AxiosPromise ? R : any

// 使用
type Resp = AxiosReturnType // 泛型参数中传入你的 Api 请求函数

将某些熟悉变为可选

keysPartial

type KeysPartial = { [KinkeyofOmit] : T[K] } & { [KinU]? : T[K] }

提取可选属性

type NullableKeys = { [KinkeyofT]-?: undefined extends T[K] ? K : never }[keyofT]



参考链接