类的泛型 (Generic Classes)
在 TypeScript 中,类可以被定义为泛型(generic),这意味着它们可以处理多种类型的参数,而不仅仅是特定的数据类型。通过使用泛型类,你可以编写更加灵活和可重用的代码,同时保持类型安全。
1. 基本概念
- 泛型类:允许类接受一个或多个类型参数,在实例化时指定具体的类型。
- 类型参数:用于在类中表示不确定的具体类型,通常使用大写字母如
T、U等作为占位符。 - 类型推断: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 的实例时,可以指定具体的类型参数,例如 string 或 number。
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 类接受两个类型参数 K 和 V,分别表示键和值的类型。
示例 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 中非常强大的特性,它们允许你编写更加灵活和可重用的代码,同时保持类型安全。通过合理使用泛型类,你可以提高代码的通用性和可维护性。