TypeScript 类型系统高级技巧

TypeScript 高级类型

TypeScript 的类型系统是其最强大的特性之一,提供了静态类型检查、接口、泛型、装饰器等高级功能。掌握这些高级类型技巧可以显著提升代码质量和开发效率。

泛型(Generics)

泛型允许我们创建可重用的组件,这些组件可以支持多种类型而不失去类型安全性。

// 基本泛型函数
function identity(arg: T): T {
    return arg;
}

// 使用
let output1 = identity("hello");
let output2 = identity(42);
let output3 = identity("TypeScript"); // 类型推断

// 泛型接口
interface GenericIdentityFn {
    (arg: T): T;
}

// 泛型类
class GenericNumber {
    zeroValue: T;
    add: (x: T, y: T) => T;
}

let myGenericNumber = new GenericNumber();
myGenericNumber.zeroValue = 0;
myGenericNumber.add = (x, y) => x + y;

条件类型(Conditional Types)

条件类型允许我们根据类型关系选择不同的类型,这是TypeScript类型系统的高级功能。

// 条件类型示例
type IsString = T extends string ? true : false;

type A = IsString; // true
type B = IsString; // false

// 条件类型与infer关键字
type ReturnType = T extends (...args: any[]) => infer R ? R : any;

function getUser() {
    return { name: "John", age: 30 };
}

type User = ReturnType; // { name: string; age: number }

映射类型(Mapped Types)

映射类型允许我们基于旧类型创建新类型,这在处理对象类型时特别有用。

// 只读映射类型
type Readonly = {
    readonly [P in keyof T]: T[P];
};

// 可选映射类型
type Partial = {
    [P in keyof T]?: T[P];
};

// 实际应用
interface User {
    id: number;
    name: string;
    email: string;
}

type ReadonlyUser = Readonly;
// 等同于:
// {
//     readonly id: number;
//     readonly name: string;
//     readonly email: string;
// }

type PartialUser = Partial;
// 等同于:
// {
//     id?: number;
//     name?: string;
//     email?: string;
// }

// 实用工具类型
type Pick = {
    [P in K]: T[P];
};

type Omit = Pick>;

// 使用示例
type UserBasicInfo = Pick;
type UserWithoutEmail = Omit;

装饰器(Decorators)

装饰器是一种特殊类型的声明,可以附加到类声明、方法、访问器、属性或参数上,用于修改类的行为。

// 类装饰器
function LogClass(target: Function) {
    console.log(`类 ${target.name} 被装饰`);
}

function AddTimestamp(constructor: Function) {
    constructor.prototype.createdAt = new Date();
}

// 方法装饰器
function LogMethod(target: any, propertyKey: string, descriptor: PropertyDescriptor) {
    const originalMethod = descriptor.value;
    
    descriptor.value = function(...args: any[]) {
        console.log(`调用方法: ${propertyKey}`);
        console.log(`参数: ${JSON.stringify(args)}`);
        const result = originalMethod.apply(this, args);
        console.log(`返回值: ${result}`);
        return result;
    };
    
    return descriptor;
}

// 属性装饰器
function DefaultValue(value: any) {
    return function(target: any, propertyKey: string) {
        Object.defineProperty(target, propertyKey, {
            get: function() {
                return this[`_${propertyKey}`] || value;
            },
            set: function(newValue) {
                this[`_${propertyKey}`] = newValue;
            },
            enumerable: true,
            configurable: true
        });
    };
}

// 使用装饰器
@LogClass
@AddTimestamp
class UserService {
    @DefaultValue("default user")
    username: string;
    
    constructor(username?: string) {
        if (username) this.username = username;
    }
    
    @LogMethod
    greet(message: string): string {
        return `${message}, ${this.username}!`;
    }
}

类型体操实用技巧

1. 类型守卫(Type Guards)

// 自定义类型守卫
function isString(value: any): value is string {
    return typeof value === "string";
}

function processValue(value: string | number) {
    if (isString(value)) {
        // 这里value被推断为string类型
        console.log(value.toUpperCase());
    } else {
        // 这里value被推断为number类型
        console.log(value.toFixed(2));
    }
}

2. 索引签名(Index Signatures)

interface StringDictionary {
    [key: string]: string;
}

interface NumberOrStringDictionary {
    [key: string]: number | string;
    length: number; // 必须与索引签名兼容
    name: string;
}

3. 模板字面量类型(Template Literal Types)

// TypeScript 4.1+
type HttpMethod = "GET" | "POST" | "PUT" | "DELETE";
type ApiEndpoint = `/api/${string}`;
type FullApiPath = `${HttpMethod} ${ApiEndpoint}`;

type EventName = "click" | "change" | "input";
type HandlerName = `on${Capitalize}`;
// 结果为: "onClick" | "onChange" | "onInput"

TypeScript的高级类型系统为大型项目提供了强大的类型安全保障。通过掌握这些高级技巧,您可以编写出更健壮、更易维护的代码,并充分利用TypeScript的类型检查能力。