类型编程套路
映射类型处理
ts
// key 类型限制为string
type Foo = {
[key: string]: string;
};
// 通过in 限定key 为"id”或“name”
type Foo = {
[key in "id" | "name"]: string;
};
/**
* 通过keyof 获取User 的key 的联合类型,然后UserKeys 的key 限定为User 的key
*/
type User = {
id: number;
name: string;
age: number;
};
type UserKeys = {
[key in keyof User]: string;
};
/**
* 包含修饰符情况
*/
type Person = {
readonly id: number;
name: string;
age?: number;
};
type PersonKeys = {
[key in keyof Person]: Person[key];
};
// { readonly id: string; name: string; age?: string; }
/**
* 通用性
*/
type CopyKeys<T extends object> = {
[key in keyof T]: T[key];
};infer 类型推断
联合类型分发
递归复用遍历
ts
// 将数组倒序
type Reverse<T extends any[]> = T extends [...infer F, infer L]
? [L, ...Reverse<F>]
: [];
type R1 = Reverse<["a", "b", "c"]>; // ["c", "b", "a"]分发逆变推断
ts
// 实现工具:将联合类型转变成交叉类型
// 利用分发特性,将联合类型构建成联合类型的函数
type UnionToIntersection<T> = (
T extends any ? (arg: T) => any : never
) extends (arg: infer R) => any
? R
: never;
type B = UnionToIntersection<{ name: "zhangsan" } | { id: 1 }>;
// { name: "zhangsan" } & { id: 1 }
// 实现工具:将元组类型转变为交叉类型
type TupleToUnion<T extends any[]> = T extends [infer F, ...infer R]
? F & TupleToUnion<R>
: unknown;
// unknown,用于最后收尾,不能使用any 和never,否则最后类型会变成any 或never
type C = TupleToUnion<[{ id: 1 }, { name: "zhangsan" }]>;
// {id: 1} & {name: 'zhangsan'}