泛型(Generics)是 TypeScript 中的一种特性,允许你编写可重用的组件,这些组件可以处理多种类型而不是单一类型。泛型通过参数化类型来提高代码的灵活性和可重用性,同时保持类型安全。
泛型的基本概念
泛型允许你在定义函数、类、接口时使用类型参数,这些类型参数在使用时可以被具体的类型替换。通过泛型,你可以编写更通用、更灵活的代码。
泛型的语法
泛型通常使用 <T>
来表示类型参数,其中 T
是一个占位符,表示某种类型。你可以使用任何有效的标识符来代替 T
,例如 <U>
、<V>
等。
示例
1. 泛型函数
以下是一个简单的泛型函数示例,它返回传入的参数:
function identity<T>(arg: T): T {
return arg;
}
let output1 = identity<string>("hello"); // 类型为 string
let output2 = identity<number>(42); // 类型为 number
在这个例子中,identity
函数使用了泛型类型参数 T
,它可以接受任何类型的参数并返回相同类型的值。
2. 泛型类
以下是一个泛型类的示例,它表示一个简单的容器:
class Container<T> {
private value: T;
constructor(value: T) {
this.value = value;
}
getValue(): T {
return this.value;
}
}
let numberContainer = new Container<number>(42);
console.log(numberContainer.getValue()); // 输出: 42
let stringContainer = new Container<string>("hello");
console.log(stringContainer.getValue()); // 输出: hello
在这个例子中,Container
类使用了泛型类型参数 T
,它可以存储任何类型的值。
3. 泛型接口
以下是一个泛型接口的示例,它描述了一个包含 value
属性的对象:
interface KeyValuePair<K, V> {
key: K;
value: V;
}
let pair1: KeyValuePair<number, string> = { key: 1, value: "hello" };
let pair2: KeyValuePair<string, boolean> = { key: "enabled", value: true };
在这个例子中,KeyValuePair
接口使用了两个泛型类型参数 K
和 V
,分别表示键和值的类型。
4. 泛型约束
有时你可能希望限制泛型类型参数的类型范围,这时可以使用泛型约束。以下是一个使用泛型约束的示例:
interface Lengthwise {
length: number;
}
function loggingIdentity<T extends Lengthwise>(arg: T): T {
console.log(arg.length); // OK,因为 T 继承了 Lengthwise 接口
return arg;
}
loggingIdentity("hello"); // OK,字符串有 length 属性
loggingIdentity([1, 2, 3]); // OK,数组有 length 属性
loggingIdentity({ length: 10, value: 42 }); // OK,对象有 length 属性
loggingIdentity(42); // Error: 数字没有 length 属性
在这个例子中,loggingIdentity
函数使用了泛型约束 T extends Lengthwise
,表示 T
必须具有 length
属性。
5. 泛型默认类型
你可以为泛型类型参数指定默认类型,当使用时不提供类型参数时,将使用默认类型:
function createArray<T = string>(length: number, value: T): T[] {
return Array(length).fill(value);
}
let stringArray = createArray(3, "hello"); // 类型为 string[]
let numberArray = createArray<number>(3, 42); // 类型为 number[]
在这个例子中,createArray
函数的泛型类型参数 T
默认为 string
。
泛型的优势
- 代码重用:泛型允许你编写可重用的组件,这些组件可以处理多种类型。
- 类型安全:泛型在编译时进行类型检查,确保类型安全。
- 灵活性:泛型提供了更高的灵活性,允许你编写更通用的代码。
总结
泛型是 TypeScript 中用于编写可重用、类型安全的组件的重要特性。通过泛型,你可以定义函数、类、接口等,使其能够处理多种类型而不是单一类型。理解泛型的使用场景和语法,可以帮助你编写出更灵活、更安全的代码。