TypeScript 5.x 类型体操实战指南

TypeScript 5.x 类型体操实战指南

TypeScript 的类型系统远比大多数人想象的强大。掌握高级类型技巧,可以让你在编译期就捕获更多错误,减少运行时 bug。本文通过一系列递进案例,带你进入类型体操的世界。

条件类型是高级类型的基础:

示意图
示意图
// 提取 Promise 内部类型
type UnwrapPromise<T> = T extends Promise<infer U> ? U : T;

type Result = UnwrapPromise<Promise<string>>; // string

// 递归解包
type DeepUnwrap<T> = T extends Promise<infer U>
    ? DeepUnwrap<U>
    : T;

type Nested = DeepUnwrap<Promise<Promise<number>>>; // number

模板字面量类型可以生成精确的字符串类型:

// CSS 属性类型
type CSSProperty = keyof React.CSSProperties;

// 事件处理器类型
type EventHandler<T extends string> = `on${Capitalize<T>}`;

type ClickHandler = EventHandler<"click">; // "onClick"
type ChangeHandler = EventHandler<"change">; // "onChange"

// 路由参数提取
type ExtractParams<T extends string> =
    T extends `${string}:${infer Param}/${infer Rest}`
        ? { [K in Param | keyof ExtractParams<Rest>]: string }
        : T extends `${string}:${infer Param}`
        ? { [K in Param]: string }
        : {};

映射类型结合条件类型,可以实现强大的类型转换:

// 将所有可选属性变为必需,并添加默认值
type WithDefaults<T, Defaults extends Partial<T>> = {
    [K in keyof T]-?: T[K] | Defaults[K];
};

// 深层 Partial
type DeepPartial<T> = {
    [K in keyof T]?: T[K] extends object ? DeepPartial<T[K]> : T[K];
};

这些技巧在我们的组件库开发中发挥了巨大作用。通过精确的类型定义,我们实现了 100% 的类型覆盖,IDE 自动补全体验大幅提升,组件 API 的误用在编译期就能被发现。