Partial
Partial<T>将T的所有属性变成可选的。
/*核心实现就是通过映射类型遍历T上所有的属性,然后将每个属性设置为可选属性*/
type Partial<T> = { [P in keyof T]?: T[P]; }
//改造
type PartialOptional<T, K extends keyof T> = { [P in K]?: T[P]; }
/** * @example * type Eg1 = { key1?: string; key2?: number } */
type Eg1 = PartialOptional<{ key1: string, key2: number, key3: '' }, 'key1' | 'key2'>;
Readonly
type Readonly<T> = { readonly [P in keyof T]: T[P] }
Pick
type Pick<T, K extends keyof T> = { [P in K]: T[P]; };
Record
构造一个type,key是第一个参数联合类型中的每一个子类型,类型就是第二个参数
/**
* @example
* type Eg1 = {
* a: { key1: string; };
* b: { key1: string; };
* }
* @desc 就是遍历第一个参数'a' | 'b'的每个子类型,然后将值设置为第二参数
*/
type Eg1 = Record<'a' | 'b', {key1: string}>
//具体实现
type Record<K extends keyof any, T> = { [P in K]: T }
- 值得注意的是
keyof any得到的是string | number | symbol - 原因在于类型key的类型只能为
string | number | symbol
Exclude
Exclude<T, U>提取存在于T,但不存在于U的类型组成的联合类型。
type Exclude<T, U> = T extends U ? never : T;
Record
构造一个type,key是第一个参数联合类型中的每一个子类型,类型就是第二个参数
type Exclude<T, U> = T extends U ? never : T;
/**
* @example
* type Eg = 'key1'
*/
type Eg = Exclude<'key1' | 'key2', 'key2'>
Extract
Extract<T, U>提取联合类型T和联合类型U的所有交集。
type Extract<T, U> = T extends U ? T : never;
Omit原理解析
Omit<T, K>从类型T中剔除K中的所有属性。
type Omit = Pick<T, Exclude<keyof T, K>>;
Parameters 和 ReturnType
Parameters 获取函数的参数类型,将每个参数类型放在一个元组中 ReturnType 获取函数的返回值类型。
infer关键词只能在extends条件类型上使用,不能在其他地方使用。- 只能在正确的分支上
/**
* @desc 具体实现
*/
type Parameters<T extends (...args: any) => any> = T extends (...args: infer P) => any ? P : never;
/**
* @example * type Eg = [arg1: string, arg2: number];
*/
type Eg = Parameters<(arg1: string, arg2: number) => void>;
/**
* @desc ReturnType的实现其实和Parameters的基本一样
* 无非是使用infer R的位置不一样。
*/
type ReturnType<T extends (...args: any) => any> = T extends (...args: any) => infer R ? R : any;
扩展:infer实现一个推导数组所有元素的类型:
/**
* 约束参数T为数组类型,
* 判断T是否为数组,如果是数组类型则推导数组元素的类型
*/
type FalttenArray<T extends Array<any>> = T extends Array<infer P> ? P : never;
/**
* type Eg1 = number | string;
*/
type Eg1 = FalttenArray<[number, string]>
/**
* type Eg2 = 1 | 'asd';
*/
type Eg2 = FalttenArray<[1, 'asd']>
自定义类型
SymmetricDifference
SymmetricDifference<T, U>获取没有同时存在于T和U内的类型。
type SymmetricDifference<T, U> = Exclude<T | U, T & U>;
Exclude第一个参数则是T | U,这是利用在联合类型在extends中的分发特性,可以理解为Exclude<T, T & U> | Exclude<U, T & U>;
[参考]愣锤(juejin.cn/post/699410…)