编 程 实 战

记录编程学习之路,分享技术实践经验

TypeScript

TypeScript 高级类型体操:掌握泛型与条件类型

2026-07-05 · 阅读 1,890 · 作者 编程实战

TypeScript 的类型系统是图灵完备的,这意味着你可以在类型层面实现复杂的逻辑。 掌握高级类型不仅能提升代码安全性,还能极大地改善开发体验。

泛型基础回顾

function first<T>(arr: T[]): T | undefined {
    return arr[0];
}

const a = first([1, 2, 3]);     // number | undefined
const b = first(["a", "b"]);    // string | undefined

function getProperty<T, K extends keyof T>(obj: T, key: K): T[K] {
    return obj[key];
}

条件类型

// 基础语法: T extends U ? X : Y
type IsString<T> = T extends string ? true : false;

type A = IsString<"hello">;  // true
type B = IsString<number>;   // false

// 提取 Promise 内部类型
type Unwrap<T> = T extends Promise<infer U> ? U : T;

infer 关键字

type ReturnType<T> = T extends (...args: any[]) => infer R ? R : never;
type Fn = (x: number) => string;
type R = ReturnType<Fn>;  // string

type ElementType<T> = T extends (infer E)[] ? E : T;

模板字面量类型

type EventName<T extends string> = `on${Capitalize<T>}`;
type ClickEvent = EventName<"click">;  // "onClick"

// 类型安全的事件系统
type EventMap = { click: { x: number; y: number }; focus: void; change: string };
type EventHandler<E extends keyof EventMap> = (event: EventMap[E]) => void;
type ListenerMap = {
    [K in keyof EventMap as `on${Capitalize<K>}`]: EventHandler<K>
};

映射类型实战

type DeepReadonly<T> = {
    readonly [K in keyof T]: T[K] extends object ? DeepReadonly<T[K]> : T[K];
};

type DeepPartial<T> = {
    [K in keyof T]?: T[K] extends object ? DeepPartial<T[K]> : T[K] | null;
};

实战:类型安全的 API 请求库

interface ApiRoutes {
    "/users": {
        GET: { response: { id: number; name: string }[] };
        POST: { body: { name: string }; response: { id: number } };
    };
    "/users/[id]": {
        GET: { params: { id: string }; response: { id: number; name: string } };
    };
}

async function request<
    Path extends keyof ApiRoutes,
    Method extends keyof ApiRoutes[Path]
>(path: Path, method: Method, ...args: [...]): Promise<...> {
    return {} as any;
}

const users = await request("/users", "GET");
// users 类型自动推断为 { id: number; name: string }[]
提示:高级类型虽好,但要适度使用。过于复杂的类型体操会降低代码可读性。 好的类型设计是在安全性和简洁性之间找到平衡。

总结

TypeScript 的高级类型系统为构建类型安全的应用程序提供了强大的工具。 泛型提供复用性,条件类型和 infer 提供灵活性, 模板字面量类型和映射类型让字符串和对象类型变换变得简单。

← 返回首页