TypeScript 中的泛型(Generics)是一种在定义函数、接口或类时创建可重用的组件的方法,它们可以工作于多种数据类型,而不是单一的数据类型。泛型的主要目标是提供代码重用,同时保持类型安全。
泛型简介
泛型允许你编写灵活、可重用的代码,而不需要为每种数据类型编写重复的代码。你可以将类型参数(例如 T
)添加到函数、接口和类中,然后在代码中使用这些类型参数。
泛型使用方法
1. 泛型函数
泛型函数允许你在函数内部使用类型参数。
function identity<T>(arg: T): T {
return arg;
}
const output1 = identity<string>("myString"); // 类型参数为 string
const output2 = identity(42); // 类型参数由编译器自动推断为 number
2. 泛型接口
泛型接口允许你定义可重用的接口,这些接口可以接受类型参数。
interface GenericIdentityFn<T> {
(arg: T): T;
}
function identityFn<T>(arg: T): T {
return arg;
}
let myIdentity: GenericIdentityFn<number> = identityFn;
3. 泛型类
泛型类允许你在类定义中使用类型参数。
class GenericNumber<T> {
zeroValue: T;
add: (x: T, y: T) => T;
constructor(zeroValue: T, add: (x: T, y: T) => T) {
this.zeroValue = zeroValue;
this.add = add;
}
zero(): T {
return this.zeroValue;
}
addNumbers(x: T, y: T): T {
return this.add(x, y);
}
}
let myGenericNumber = new GenericNumber<number>(0, (x, y) => x + y);
4. 泛型约束
在定义泛型时,你可能希望限制可以传递给类型参数的类型。这可以通过在类型参数上设置约束来实现。
interface Lengthwise {
length: number;
}
function loggingIdentity<T extends Lengthwise>(arg: T): T {
console.log(arg.length); // 现在我们知道它有一个 length 属性
return arg;
}
loggingIdentity({length: 10, value: 3});
在这个例子中,T
被约束为实现了 Lengthwise
接口的类型。
5. 泛型与数组
泛型在数组操作中特别有用,因为它允许你创建具有特定元素类型的数组。
let list: Array<number> = [1, 2, 3];
// 或者使用泛型语法
let list2: Array<string> = ["a", "b", "c"];
// 使用泛型接口表示数组
interface NumberArray<T extends number = number> extends Array<T> {}
let numberArray: NumberArray = [1, 2, 3];
总结
泛型是 TypeScript 提供的一种强大的工具,它允许你编写灵活、可重用的代码,同时保持类型安全。通过使用泛型,你可以定义可以处理多种数据类型的函数、接口和类,而不需要为每种数据类型编写重复的代码。