Skip to content

类的泛型 (Generic Classes)

在 TypeScript 中,类可以被定义为泛型(generic),这意味着它们可以处理多种类型的参数,而不仅仅是特定的数据类型。通过使用泛型类,你可以编写更加灵活和可重用的代码,同时保持类型安全。

1. 基本概念

  • 泛型类:允许类接受一个或多个类型参数,在实例化时指定具体的类型。
  • 类型参数:用于在类中表示不确定的具体类型,通常使用大写字母如 TU 等作为占位符。
  • 类型推断:TypeScript 编译器可以根据传入的值自动推断类型参数。

2. 语法

定义泛型类

typescript
class MyClass<T> {
  constructor(private value: T) {}

  getValue(): T {
    return this.value;
  }
}

const instance1 = new MyClass<string>("Hello");
console.log(instance1.getValue()); // 输出: Hello

const instance2 = new MyClass<number>(42);
console.log(instance2.getValue()); // 输出: 42

在这个例子中,MyClass 是一个泛型类,它接受一个类型参数 T。当创建 MyClass 的实例时,可以指定具体的类型参数,例如 stringnumber

3. 示例解析

示例 1: 泛型类的基本使用

typescript
class Box<T> {
  private content: T;

  constructor(content: T) {
    this.content = content;
  }

  setContent(content: T): void {
    this.content = content;
  }

  getContent(): T {
    return this.content;
  }
}

const stringBox = new Box<string>("Hello");
console.log(stringBox.getContent()); // 输出: Hello

const numberBox = new Box<number>(42);
console.log(numberBox.getContent()); // 输出: 42

在这个例子中,Box 类是一个泛型类,它可以存储任意类型的值,并提供方法来设置和获取该值。

示例 2: 多个类型参数

typescript
class KeyValuePair<K, V> {
  private key: K;
  private value: V;

  constructor(key: K, value: V) {
    this.key = key;
    this.value = value;
  }

  getKey(): K {
    return this.key;
  }

  getValue(): V {
    return this.value;
  }
}

const pair1 = new KeyValuePair<string, number>("age", 30);
console.log(pair1.getKey(), pair1.getValue()); // 输出: age 30

const pair2 = new KeyValuePair<number, string>(1, "one");
console.log(pair2.getKey(), pair2.getValue()); // 输出: 1 one

在这个例子中,KeyValuePair 类接受两个类型参数 KV,分别表示键和值的类型。

示例 3: 使用约束条件

有时你可能希望限制泛型类可以接受的类型,以确保某些操作是合法的。这可以通过使用类型约束来实现。

typescript
interface Printable {
  print(): void;
}

class Printer<T extends Printable> {
  private item: T;

  constructor(item: T) {
    this.item = item;
  }

  printItem(): void {
    this.item.print();
  }
}

class Document implements Printable {
  print() {
    console.log("Printing document...");
  }
}

const printer = new Printer(new Document());
printer.printItem(); // 输出: Printing document...

在这个例子中,Printer 类的类型参数 T 被约束为必须实现 Printable 接口。这样可以确保 printItem 方法调用 item.print() 是安全的。

示例 4: 默认类型参数

从 TypeScript 4.7 开始,泛型类可以指定默认类型参数,以便在未提供具体类型时使用默认类型。

typescript
class Container<T = string> {
  private items: T[] = [];

  addItem(item: T): void {
    this.items.push(item);
  }

  getItems(): T[] {
    return this.items;
  }
}

const stringContainer = new Container();
stringContainer.addItem("Hello");
console.log(stringContainer.getItems()); // 输出: ["Hello"]

const numberContainer = new Container<number>();
numberContainer.addItem(42);
console.log(numberContainer.getItems()); // 输出: [42]

在这个例子中,Container 类的类型参数 T 有一个默认类型 string。如果在实例化时没有指定类型参数,则使用默认类型。

4. 应用场景

  • 容器类:如栈、队列、链表等数据结构,可以通过泛型类来处理不同类型的元素。
  • 工具类:如缓存、工厂模式等,可以通过泛型类来支持多种类型的对象。
  • UI 组件:如按钮、输入框等,可以通过泛型类来处理不同类型的数据绑定。
  • API 客户端:如 RESTful API 客户端,可以通过泛型类来处理不同的响应类型。

5. 总结

泛型类是 TypeScript 中非常强大的特性,它们允许你编写更加灵活和可重用的代码,同时保持类型安全。通过合理使用泛型类,你可以提高代码的通用性和可维护性。

Released under the MIT License.