typescript高级类型

Record

Record<K,V> 创建一个以 K 为属性的类型,以 V 为值类型的对象。

  • 使用 Record 快速创建具有约束性质的对象类型
1
2
3
4
5
6
7
8
type ISubject = "Math" | "Chinese" | "English";
type IGrade = Record<ISubject, number>;

const myGrade: IGrade = {
Math: 99,
Chinese: 100,
English: 99,
};

Partial

Partial<T> T 是一个对象类型,这是取 T 这个对象的部分键值对作为属性,原理如下:

  • keyof 是取对象类型的所有的属性 in 是取其中属性之一
1
2
3
4
5
6
type IPartial<T extends Record<any, any>> = {
[P in keyof T]?: T[P];
};
const mathGrade: IPartial<IGrade> = {
Math: 100,
};
  • Record 结合 Partial 实现 AB 对象合并,A 对象如果有 B 对象的值就替换 B 对象
  • A 对象是 B 对象的一部分故而就是 Partial 实现,T 也需要泛型约束
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
type IMerge<T extends Record<string, any>> = (
sourceObj: Partial<T>,
targetObj: T
) => T;
type ITargetObj = {
name: "hhhh";
age: 999;
};
const merge: IMerge<ITargetObj> = (sourceObj, targetObj) => {
for (let key in targetObj) {
const itemVal = sourceObj[key];
itemVal && (targetObj[key] = itemVal);
}
return targetObj;
};

条件类型

extends 的使用

  • 如果在泛型<>中使用就是表示泛型约束 比如 <T extends Record<string,any>>表示的是传入的泛型 T 必须是属性是字符串,值任意类型的对象
  • 如果 extends 紧跟泛型后面就表示条件类型,T 继承 U 那么结果就是 X 类型,否则就是 Y 类型
1
type Test<T, U, V> = T extends Record<string, string> ? U : V;

infer

infer 表示在 extends 条件语句中待推断的类型变量

1
type ParamType<T> = T extends (arg: infer P) => any ? P : T;
  • 在这个条件语句 T extends (arg: infer P) => any ? P : T 中,infer P 表示待推断的函数参数。 整句表示为:如果 T 能赋值给 (arg: infer P) => any,则结果是 (arg: infer P) => any 类型中的参数 P,否则返回为 T。
1
2
3
4
5
6
7
8
9
interface User {
name: string;
age: number;
}

type Func = (user: User) => void;

type Param = ParamType<Func>; // Param = User
type AA = ParamType<string>; // string

ReturnType

ReturnType<T> 表示函数返回值的类型,实现原理如下

  • T 如果是这个函数,则把函数返回值的类型导出即可,这里使用到了 infer,infer 是等待推断的类型,这里需要推断的类型是返回值的类型,就是把 infer 的值当做一个变量来使用
1
2
3
4
5
type IReturnType<T extends (...args: any) => any> = T extends (
...args: any
) => infer R
? R
: any;

typescript高级类型
https://sunburst89757.github.io/2022/08/02/ts-learning/
作者
Sunburst89757
发布于
2022年8月2日
许可协议