TypeScript 类型体操入门
学习 TypeScript 高级类型编程技巧,从基础到进阶的类型体操指南。
TypeScript 的类型系统是图灵完备的,这意味着你可以用类型做很多有趣的事情。让我们从基础开始,逐步探索类型体操的世界。
基础类型工具
条件类型
条件类型是类型体操的基础:
type IsString<T> = T extends string ? true : false;
type A = IsString<"hello">; // truetype B = IsString<42>; // false映射类型
映射类型允许你转换对象类型的每个属性:
type Readonly<T> = { readonly [K in keyof T]: T[K];};
type Optional<T> = { [K in keyof T]?: T[K];};实用类型实现
实现 Pick
type MyPick<T, K extends keyof T> = { [P in K]: T[P];};
interface User { id: number; name: string; email: string;}
type UserPreview = MyPick<User, "id" | "name">;// { id: number; name: string }实现 Omit
type MyOmit<T, K extends keyof T> = { [P in keyof T as P extends K ? never : P]: T[P];};
type UserWithoutEmail = MyOmit<User, "email">;// { id: number; name: string }递归类型
TypeScript 支持递归类型定义:
type DeepReadonly<T> = { readonly [K in keyof T]: T[K] extends object ? DeepReadonly<T[K]> : T[K];};
type NestedObject = { a: { b: { c: number; }; };};
type ReadonlyNested = DeepReadonly<NestedObject>;模板字面量类型
TypeScript 4.1 引入了模板字面量类型:
type EventName<T extends string> = `on${Capitalize<T>}`;
type ClickEvent = EventName<"click">; // "onClick"type FocusEvent = EventName<"focus">; // "onFocus"
// 更复杂的例子type CSSProperty = "margin" | "padding";type CSSDirection = "top" | "right" | "bottom" | "left";
type CSSSpacing = `${CSSProperty}-${CSSDirection}`;// "margin-top" | "margin-right" | ... | "padding-left"类型推断
使用 infer 关键字提取类型:
type ReturnType<T> = T extends (...args: any[]) => infer R ? R : never;
type ArrayElement<T> = T extends (infer E)[] ? E : never;
type Fn = () => string;type Result = ReturnType<Fn>; // string
type Arr = number[];type Elem = ArrayElement<Arr>; // number实战:类型安全的事件系统
type Events = { click: { x: number; y: number }; focus: { target: HTMLElement }; submit: { data: FormData };};
type EventHandler<E extends keyof Events> = ( event: Events[E]) => void;
function on<E extends keyof Events>( event: E, handler: EventHandler<E>): void { // 实现}
// 类型安全的使用on("click", (e) => { console.log(e.x, e.y); // ✅ 类型正确});
on("submit", (e) => { console.log(e.data); // ✅ 类型正确});类型体操不仅是炫技,更是构建类型安全应用的有力工具。掌握这些技巧,让编译器成为你最好的助手。