Partial
Partial 作用是将传入的属性变为可选项.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<T> = { [P in keyof T]?: T[P] };
上面语句的意思是 keyof T
拿到 T 所有属性名, 然后 in
进行遍历, 将值赋给 P, 最后 T[P]
取得相应属性的值.
结合中间的 ?
我们就明白了 Partial
的含义了.
Required
Required 的作用是将传入的属性变为必选项, 源码如下
type Required<T> = { [P in keyof T]-?: T[P] };
-?
这里很好理解,就是将可选项代表的 ?
去掉, 从而让这个类型变成必选项. 与之对应的还有个+?
, 这个含义自然与-?
之前相反, 它是用来把属性变成可选项的.
Mutable
将 T 的所有属性的 readonly 移除.
type Mutable<T> = {
-readonly [P in keyof T]: T[P]
}
Readonly
将传入的属性变为只读选项, 源码如下
type Readonly<T> = { readonly [P in keyof T]: T[P] };
Record
将 K 中所有的属性的值转化为 T 类型
type Record<K extends keyof any, T> = { [P in K]: T };
Pick
从 T 中取出 一系列 K 的属性
type Pick<T, K extends keyof T> = { [P in K]: T[P] };
Exclude
首先介绍一下条件类型:
如果 T 是 U 的子类型的话,那么就会返回 X,否则返回 Y
T extends U ? X : Y
甚至可以组合多个
type TypeName<T> =
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
源码:
从 T 中找出 U 中没有的元素, 换种更加贴近语义的说法其实就是从T 中排除 U
type Exclude<T, U> = T extends U ? never : T;
例如:
type T = Exclude<1 | 2, 1 | 3> // -> 2
Extract
提取出 T 包含在 U 中的元素, 换种更加贴近语义的说法就是从 T 中提取出 U.
type Extract<T, U> = T extends U ? T : never;
Omit
用之前的 Pick 和 Exclude 进行组合, 实现忽略对象某些属性功能.
type Omit = Pick<T, Exclude<keyof T, K>>
例如:
type Foo = Omit<{name: string, age: number}, 'name'> // -> { age: number }
ReturnType
首先介绍一下infer
关键字。我们可以用 infer
声明一个类型变量并且对它进行使用。
例如,获取函数的返回类型:
type ReturnType<T> = T extends (
...args: any[]
) => infer R
? R
: any;
这里的 infer R
就是声明一个变量来承载传入函数签名的返回值类型, 简单说就是用它取到函数返回值的类型方便之后使用.
ReturnType
用法:
function foo(x: number): Array<number> {
return [x];
}
type fn = ReturnType<typeof foo>;
AxiosReturnType
开发经常使用 axios 进行封装 API层 请求, 通常是一个函数返回一个 AxiosPromise<Resp>
, 现在我想取到它的 Resp 类型, 根据上一个工具泛型的知识我们可以这样写.
import { AxiosPromise } from 'axios' // 导入接口
type AxiosReturnType<T> =
T extends (...args: any[]) => AxiosPromise<infer R> ? R : any
// 使用
type Resp = AxiosReturnType<Api> // 泛型参数中传入你的 Api 请求函数