TypeScript泛型类 #

一、泛型类基础 #

1.1 什么是泛型类 #

泛型类是带有类型参数的类,可以在实例化时指定具体的类型。

typescript
class Box<T> {
    private value: T;
    
    constructor(value: T) {
        this.value = value;
    }
    
    getValue(): T {
        return this.value;
    }
    
    setValue(value: T): void {
        this.value = value;
    }
}

const stringBox = new Box<string>('hello');
const numberBox = new Box<number>(123);

console.log(stringBox.getValue());
console.log(numberBox.getValue());

1.2 类型推断 #

typescript
const box = new Box('hello');

const box2 = new Box<string>(123);

二、泛型类成员 #

2.1 泛型属性 #

typescript
class Container<T> {
    value: T;
    
    constructor(value: T) {
        this.value = value;
    }
}

const container = new Container<string>('hello');
console.log(container.value);

2.2 泛型方法 #

typescript
class Calculator<T> {
    add(a: T, b: T): T {
        return a;
    }
}

class MathCalculator<T extends number> {
    add(a: T, b: T): T {
        return (a + b) as T;
    }
}

2.3 静态成员 #

静态成员不能使用类的类型参数:

typescript
class Box<T> {
    private value: T;
    
    static defaultValue: T;
    
    static create<T>(value: T): Box<T> {
        return new Box(value);
    }
}

三、泛型约束 #

3.1 extends约束 #

typescript
interface Lengthwise {
    length: number;
}

class Container<T extends Lengthwise> {
    private value: T;
    
    constructor(value: T) {
        this.value = value;
    }
    
    getLength(): number {
        return this.value.length;
    }
}

const container1 = new Container('hello');
const container2 = new Container([1, 2, 3]);
const container3 = new Container(123);

3.2 多重约束 #

typescript
interface Serializable {
    serialize(): string;
}

interface Cloneable {
    clone(): this;
}

class DataManager<T extends Serializable & Cloneable> {
    private data: T;
    
    constructor(data: T) {
        this.data = data;
    }
    
    serialize(): string {
        return this.data.serialize();
    }
    
    clone(): T {
        return this.data.clone();
    }
}

3.3 构造函数约束 #

typescript
class Factory<T> {
    private instance: T;
    
    constructor(private ctor: new (...args: any[]) => T, ...args: any[]) {
        this.instance = new ctor(...args);
    }
    
    getInstance(): T {
        return this.instance;
    }
}

class User {
    constructor(public name: string) {}
}

const factory = new Factory(User, 'Alice');
console.log(factory.getInstance().name);

四、多类型参数 #

4.1 多个类型参数 #

typescript
class Pair<K, V> {
    constructor(
        public key: K,
        public value: V
    ) {}
}

const pair = new Pair('name', 'Alice');
console.log(pair.key, pair.value);

4.2 键值对存储 #

typescript
class Dictionary<K extends string | number | symbol, V> {
    private items: Map<K, V> = new Map();
    
    set(key: K, value: V): void {
        this.items.set(key, value);
    }
    
    get(key: K): V | undefined {
        return this.items.get(key);
    }
    
    has(key: K): boolean {
        return this.items.has(key);
    }
    
    delete(key: K): boolean {
        return this.items.delete(key);
    }
    
    keys(): K[] {
        return Array.from(this.items.keys());
    }
    
    values(): V[] {
        return Array.from(this.items.values());
    }
}

五、泛型默认值 #

5.1 基本默认值 #

typescript
class Container<T = string> {
    constructor(public value: T) {}
}

const container1 = new Container('hello');
const container2 = new Container<number>(123);

5.2 复杂默认值 #

typescript
interface Config {
    timeout: number;
    retries: number;
}

class ApiClient<T extends Config = { timeout: number; retries: number }> {
    constructor(private config: T) {}
    
    getConfig(): T {
        return this.config;
    }
}

const client1 = new ApiClient({ timeout: 5000, retries: 3 });
const client2 = new ApiClient<{ timeout: number; retries: number; baseUrl: string }>({
    timeout: 5000,
    retries: 3,
    baseUrl: 'https://api.example.com'
});

六、泛型继承 #

6.1 泛型类继承 #

typescript
class Base<T> {
    constructor(public value: T) {}
}

class Derived<T> extends Base<T> {
    getValue(): T {
        return this.value;
    }
}

const derived = new Derived('hello');
console.logderived.getValue());

6.2 固定类型参数 #

typescript
class Base<T> {
    constructor(public value: T) {}
}

class StringDerived extends Base<string> {
    toUpperCase(): string {
        return this.value.toUpperCase();
    }
}

const derived = new StringDerived('hello');
console.log(derived.toUpperCase());

6.3 添加新的类型参数 #

typescript
class Base<T> {
    constructor(public value: T) {}
}

class Derived<T, U> extends Base<T> {
    constructor(value: T, public extra: U) {
        super(value);
    }
}

const derived = new Derived('hello', 123);
console.log(derived.value, derived.extra);

七、实用示例 #

7.1 响应式数据 #

typescript
class Reactive<T> {
    private value: T;
    private subscribers: ((value: T) => void)[] = [];
    
    constructor(initialValue: T) {
        this.value = initialValue;
    }
    
    get(): T {
        return this.value;
    }
    
    set(newValue: T): void {
        this.value = newValue;
        this.notify();
    }
    
    subscribe(callback: (value: T) => void): () => void {
        this.subscribers.push(callback);
        return () => {
            const index = this.subscribers.indexOf(callback);
            if (index !== -1) {
                this.subscribers.splice(index, 1);
            }
        };
    }
    
    private notify(): void {
        this.subscribers.forEach(callback => callback(this.value));
    }
}

const counter = new Reactive(0);
const unsubscribe = counter.subscribe(value => {
    console.log(`Counter: ${value}`);
});

counter.set(1);
counter.set(2);
unsubscribe();

7.2 栈数据结构 #

typescript
class Stack<T> {
    private items: T[] = [];
    
    push(item: T): void {
        this.items.push(item);
    }
    
    pop(): T | undefined {
        return this.items.pop();
    }
    
    peek(): T | undefined {
        return this.items[this.items.length - 1];
    }
    
    isEmpty(): boolean {
        return this.items.length === 0;
    }
    
    size(): number {
        return this.items.length;
    }
    
    clear(): void {
        this.items = [];
    }
}

const stack = new Stack<number>();
stack.push(1);
stack.push(2);
stack.push(3);

console.log(stack.pop());
console.log(stack.peek());
console.log(stack.size());

7.3 队列数据结构 #

typescript
class Queue<T> {
    private items: T[] = [];
    
    enqueue(item: T): void {
        this.items.push(item);
    }
    
    dequeue(): T | undefined {
        return this.items.shift();
    }
    
    front(): T | undefined {
        return this.items[0];
    }
    
    isEmpty(): boolean {
        return this.items.length === 0;
    }
    
    size(): number {
        return this.items.length;
    }
    
    clear(): void {
        this.items = [];
    }
}

7.4 缓存类 #

typescript
class Cache<T> {
    private items: Map<string, { value: T; expires: number }> = new Map();
    
    set(key: string, value: T, ttl: number = 3600000): void {
        this.items.set(key, {
            value,
            expires: Date.now() + ttl
        });
    }
    
    get(key: string): T | null {
        const item = this.items.get(key);
        if (!item) {
            return null;
        }
        
        if (Date.now() > item.expires) {
            this.items.delete(key);
            return null;
        }
        
        return item.value;
    }
    
    has(key: string): boolean {
        return this.get(key) !== null;
    }
    
    delete(key: string): boolean {
        return this.items.delete(key);
    }
    
    clear(): void {
        this.items.clear();
    }
}

八、泛型类设计模式 #

8.1 工厂模式 #

typescript
interface Product {
    operation(): string;
}

abstract class Factory<T extends Product> {
    abstract create(): T;
    
    doSomething(): string {
        const product = this.create();
        return product.operation();
    }
}

class ConcreteProduct implements Product {
    operation(): string {
        return 'ConcreteProduct operation';
    }
}

class ConcreteFactory extends Factory<ConcreteProduct> {
    create(): ConcreteProduct {
        return new ConcreteProduct();
    }
}

8.2 建造者模式 #

typescript
class QueryBuilder<T> {
    private conditions: string[] = [];
    
    where(condition: string): this {
        this.conditions.push(condition);
        return this;
    }
    
    build(): { table: string; conditions: string[] } {
        return {
            table: '',
            conditions: this.conditions
        };
    }
}

九、总结 #

本章介绍了TypeScript泛型类:

泛型类特点 #

  1. 带有类型参数的类
  2. 实例化时指定具体类型
  3. 支持类型推断
  4. 静态成员不能使用类型参数

泛型约束 #

  1. extends约束类型范围
  2. 多重约束
  3. 构造函数约束

最佳实践 #

  1. 使用泛型提高代码复用性
  2. 合理使用约束限制类型
  3. 为泛型参数提供默认值
  4. 使用泛型实现通用数据结构
最后更新:2026-03-26