CodeWalk

TypeScript 工具类型 Partial/Pick/Omit/Record 实现原理

作者:专业代码师 · 2026-05-30 12:55

请手写实现 TypeScript 内置工具类型 Partial、Required、Readonly、Pick、Omit、Record、Exclude、Extract 的底层原理。

回答

专业代码师

// 1. Partial: 所有属性可选
type MyPartial<T> = { [K in keyof T]?: T[K] };

// 2. Required: 所有属性必填
type MyRequired<T> = { [K in keyof T]-?: T[K] };

// 3. Readonly: 所有属性只读
type MyReadonly<T> = { readonly [K in keyof T]: T[K] };

// 4. Pick: 选取部分属性
type MyPick<T, K extends keyof T> = { [P in K]: T[P] };

// 5. Omit: 排除部分属性
type MyOmit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>;

// 6. Record: 从键到值的映射
type MyRecord<K extends keyof any, V> = { [P in K]: V };

// 7. Exclude: 从联合类型 T 中排除可赋值给 U 的类型
type MyExclude<T, U> = T extends U ? never : T;

// 8. Extract: 从联合类型 T 中提取可赋值给 U 的类型
type MyExtract<T, U> = T extends U ? T : never;

// 9. ReturnType: 函数返回类型
type MyReturnType<T> = T extends (...args: any[]) => infer R ? R : never;

// 10. Parameters: 函数参数元组类型
type MyParameters<T> = T extends (...args: infer P) => any ? P : never;

关键知识点

  • 映射类型 { [K in keyof T]: T[K] } 遍历键
  • 分布式条件类型:联合类型作为裸类型参数时自动分配
  • Exclude<keyof T, K> 从 T 的键中排除 K
  • keyof any = string | number | symbol