条件类型下的类型提取
更新时间:2024-04-08阅读整篇大约4分钟
infer用于对条件类型下的一部分类型进行提取
对于数组类型的提取
ts
//数组类型
//1.提取第一个元素
type PickFirstType<T extends unknown[]> = T extends [infer R, ...any[]] ? R : never;
//2.提取最后一个元素
type PickLastType<T extends unknown[]> = T extends [...any[], infer R] ? R : never;
//3.提取中间的元素
type PickMiddleType<T extends unknown[]> = T extends [unknown, ...infer R, unknown] ? R : never;
//4.指定下标,也可以通过 typeof
type PickIndexType<T extends unknown[], I extends number> = T[I];
declare const test_1: PickFirstType<[1, 2, '31231', 4]>;
declare const test_2: PickLastType<[1, 2, '31231', 4]>;
declare const test_3: PickMiddleType<[1, 2, '31231', 4]>;
declare const test_4: PickFirstType<[]>;//never
declare const test_5: PickIndexType<[1, 2, number], 1>;//2
对于字符串类型的提取
ts
//1.提取字符串的指定前缀剩余部分
type PickPrefix<T extends string, P extends string> = T extends `${P}${infer R}` ? R : never;
declare const b_test_1: PickPrefix<`hello world`, 'hel'>;//"lo world"
//2.提取字符串的指定后缀剩余部分
type PickSuffix<T extends string, P extends string> = T extends `${infer R}${P}` ? R : never;
declare const b_test_2: PickSuffix<`hello world`, 'rld'>;//"hello wo"
//3.替换字符
type Replace<T extends string, O extends string, N extends string> = T extends `${infer First}${O}${infer Last}` ? `${First}${N}${Last}` : never;
declare const b_test_3: Replace<`hello world!`, 'world', 'harver'>;//"hello harver!"
//4.提取非空白部分
type NonTrim<T extends string> = T extends `${infer L} ${infer R}` ? NonTrim<`${L}${R}`> : T;
declare const b_test_4: NonTrim<`hello world!`>;//"helloworld!"
declare const b_test_5: NonTrim<`hello world! `>;//"helloworld!"
declare const b_test_6: NonTrim<` hello world! `>;//"helloworld!"
declare const b_test_7: NonTrim<` h e l l o w o r l d ! `>;//"helloworld!"
对于函数类型的提取
ts
//1.获取函数中全部参数的类型集合
type PickFuncTypeArray<T extends Function> = T extends (...args: infer R) => unknown ? R : never;
const c_fn_1 = (...args: (number | string)[]) => {
return args;
};
declare const c_test_1: PickFuncTypeArray<typeof c_fn_1>;
//2.获取函数返回值类型
type PickFuncReturnType<T extends Function> = T extends (...args: unknown[]) => infer R ? R : never;
function c_fn_2(param: unknown): number {
return param as number;
};
declare const c_test_2: PickFuncReturnType<typeof c_fn_2>;//number
//3.获取this的类型
class OBJ {
name: string;
constructor() {
this.name = "dong";
}
print(this: OBJ) {
console.log(this);
}
}
const obj = new OBJ();
// obj.print.call({});//error;"strictBindCallApply": true, //是否按照原函数的类型来检查 bind、call、apply
type PickThisType<T extends Function> = T extends (this: infer R, ...args: unknown[]) => unknown ? R : never;
declare const c_test_3: PickThisType<typeof obj.print>;//OBJ
//4.提取构造器返回的类型
interface OBJFactory {
new(name: string, age: number): OBJ;
}
type PickConstructorReturnType<T extends new (...args: any[]) => unknown> = T extends new (...args: any[]) => infer R ? R : never;
declare const c_test_4: PickConstructorReturnType<OBJFactory>;//OBJ
//5.提取构造器的参数集合
type PickConstructorParamsType<T extends Function> = T extends new (...args: infer R) => unknown ? R[number] : never;
declare const c_test_5: PickConstructorParamsType<OBJFactory>;//string | number
对于索引类型的提取
ts
//1.提取某个索引的值
interface KEY {
key_1: string;
key_2: number;
key_3: symbol;
key_4: boolean;
unique: string;
}
type PickTypeByKeyof<T> = 'unique' extends keyof KEY
? KEY extends { unique: infer R; } ? R : never : never;
declare const d_test_1: PickTypeByKeyof<{ ref: "123"; name: 1312321; }>;
KEY extends { unique: infer R; }
为结构类型的赋值兼容性。当一个对象(KEY)的成员与目标类型({ unique: infer R; })
的对应成员匹配(unique),并且该对象(KEY)还具有其他额外的成员(除unique外的其他字段),那么它可以被赋值给目标类型(仅包含unique),因为它(KEY)包含了目标类型所需的所有成员。
infer仅出现在条件类型中