TypeScript高级类型编程指南


TypeScript高级类型编程指南

TypeScript的类型系统是图灵完备的,这意味着你可以用类型来实现各种复杂的逻辑。掌握高级类型编程不仅能让你写出更安全的代码,还能深入理解TypeScript的设计哲学。本文将系统地介绍TypeScript高级类型的核心概念和实战技巧。

一、泛型深入

泛型是TypeScript类型系统的基石。除了基本用法,泛型还支持默认类型参数、约束条件等高级特性:

// 泛型约束
interface HasId {
    id: number;
}

function findById<T extends HasId>(items: T[], id: number): T | undefined {
    return items.find(item => item.id === id);
}

// 多泛型参数与约束
function merge<T extends object, U extends object>(a: T, b: U): T & U {
    return { ...a, ...b };
}

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

二、条件类型

条件类型类似于三目运算符,可以根据类型条件返回不同的类型:

// 基本条件类型
type IsString<T> = T extends string ? true : false;

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

// 实用示例:提取Promise的内部类型
type UnwrapPromise<T> = T extends Promise<infer U> ? U : T;

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

// infer关键字在条件类型中用于推断类型
type ReturnType<T> = T extends (...args: any[]) => infer R ? R : any;

三、映射类型

映射类型可以从一个旧类型生成一个新类型,通过对每个属性进行变换:

// 将所有属性变为可选
type Optional<T> = {
    [K in keyof T]?: T[K];
};

// 将所有属性变为只读
type Readonly<T> = {
    readonly [K in keyof T]: T[K];
};

// 实际应用:表单验证类型
type FormErrors<T> = {
    [K in keyof T]?: string[];
};

四、模板字面量类型

TypeScript 4.1引入了模板字面量类型,可以在类型层面操作字符串:

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

// CSS属性类型安全
type CSSProperty = "margin" | "padding";
type CSSDirection = "top" | "right" | "bottom" | "left";
type CSSKey = `${CSSProperty}-${CSSDirection}`;
// "margin-top" | "margin-right" | ... | "padding-left"

五、类型体操实战

通过一些经典的类型体操练习来巩固高级类型的知识:

// DeepReadonly - 递归只读
type DeepReadonly<T> = {
    readonly [K in keyof T]: T[K] extends object
        ? DeepReadonly<T[K]>
        : T[K];
};

// PickByType - 按类型选取属性
type PickByType<T, ValueType> = {
    [K in keyof T as T[K] extends ValueType ? K : never]: T[K];
};

// 构建精确的事件系统
interface EventMap {
    click: { x: number; y: number };
    keydown: { key: string; code: number };
    resize: { width: number; height: number };
}

type EventHandler<T extends keyof EventMap> = (event: EventMap[T]) => void;

function on<T extends keyof EventMap>(event: T, handler: EventHandler<T>) {
    // 类型安全的事件监听
}

TypeScript高级类型编程是一个广阔的领域,本文仅涵盖了最核心的部分。掌握这些知识后,你可以在项目中构建出类型安全且易于维护的代码架构。记住,类型编程的最终目标是提升开发体验和代码质量,不要为了炫技而过度使用复杂的类型。


0.086730s