Skip to content

类型编程套路

映射类型处理

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'}

Released under the MIT License.