在 TypeScript 中,有时候我们希望函数或类能够处理多种类型的数据,而不局限于某一种特定类型。使用泛型可以让代码在处理不同类型时仍然保持类型安全,并且避免重复编写相似的代码。
泛型使用尖括号 <T>
来表示,其中 T
是一个类型参数,具体的类型会在使用时传入。
function identity<T>(value: T): T {
return value;
}
// 使用泛型函数
let num = identity<number>(10); // num 的类型是 number
let str = identity<string>("Hello"); // str 的类型是 string
解释:
identity
函数接受一个类型参数 T
,并返回相同类型的值。identity
时,可以传入具体的类型(如 number
或 string
),TypeScript 会自动推断出返回值的类型。泛型函数可以处理多种类型,而不需要为每种类型编写单独的函数。
function echo<T>(value: T): T {
return value;
}
let booleanValue = echo<boolean>(true); // booleanValue 的类型是 boolean
let arrayValue = echo<number[]>([1, 2, 3]); // arrayValue 的类型是 number[]
泛型接口允许你定义一个通用接口,可以与不同的类型一起使用。
interface Pair<T, U> {
first: T;
second: U;
}
let pair: Pair<string, number> = {
first: "hello",
second: 42
};
解释:
Pair<T, U>
是一个泛型接口,它有两个类型参数 T
和 U
。Pair
接口时,我们指定 T
为 string
,U
为 number
。泛型类可以定义一个适用于多种类型的类。
class Box<T> {
content: T;
constructor(content: T) {
this.content = content;
}
getContent(): T {
return this.content;
}
}
let stringBox = new Box<string>("Hello");
let numberBox = new Box<number>(123);
console.log(stringBox.getContent()); // 输出: Hello
console.log(numberBox.getContent()); // 输出: 123
解释:
Box<T>
是一个泛型类,它有一个类型参数 T
,表示存储内容的类型。Box
实例时,可以指定内容的类型,如 string
或 number
。有时候,我们希望泛型参数只能是某些类型,这时可以使用泛型约束(extends
关键字)。
interface Lengthwise {
length: number;
}
function logLength<T extends Lengthwise>(value: T): void {
console.log(value.length);
}
logLength("Hello"); // 输出: 5
logLength([1, 2, 3]); // 输出: 3
解释:
T extends Lengthwise
表示泛型参数 T
必须有 length
属性,这样可以确保 logLength
函数能够访问 length
属性。length
属性,因此可以传入 logLength
函数。泛型是 TypeScript 中用来创建灵活、可重用代码的重要特性。通过泛型,你可以编写在不同类型下都能正常工作的代码,而不用牺牲类型安全性。泛型可以应用于函数、接口和类等多种场景,为代码提供了极大的灵活性。