TypeScript泛型的介绍与应用

泛型(Generics)是 TypeScript 中一个非常强大的特性,它允许我们编写可重用的组件,这些组件可以支持多种类型,而不仅仅是单一类型。泛型的主要目的是在定义函数、接口或类时,不预先指定具体的类型,而是在使用时再指定类型。这样可以提高代码的灵活性和复用性。
泛型的基本概念
泛型通过使用类型变量(通常用 T
表示)来实现。类型变量可以捕获用户传入的类型,并在后续的代码中使用这个类型。
function identity<T>(arg: T): T {
return arg;
}
let output = identity<string>("hello"); // 输出类型为 string
let output2 = identity<number>(42); // 输出类型为 number
在这个例子中,identity
函数使用了泛型类型 T
,它可以接受任何类型的参数,并返回相同类型的值。
泛型的应用场景
-
函数和方法的泛型化:
- 当你希望函数或方法能够处理多种类型的数据时,可以使用泛型。例如,一个简单的
identity
函数可以返回任何类型的输入值。
- 当你希望函数或方法能够处理多种类型的数据时,可以使用泛型。例如,一个简单的
-
接口和类的泛型化:
- 泛型接口和类可以让你定义可重用的数据结构。例如,一个泛型的
Box
类可以存储任何类型的值。
class Box<T> { private value: T; constructor(value: T) { this.value = value; } getValue(): T { return this.value; } } let numberBox = new Box<number>(123); let stringBox = new Box<string>("hello");
- 泛型接口和类可以让你定义可重用的数据结构。例如,一个泛型的
-
泛型约束:
- 有时你可能希望泛型类型满足某些条件。你可以使用
extends
关键字来约束泛型类型。
interface Lengthwise { length: number; } function loggingIdentity<T extends Lengthwise>(arg: T): T { console.log(arg.length); // 现在我们知道 arg 有 length 属性 return arg; } loggingIdentity("hello"); // 正确,字符串有 length 属性 loggingIdentity([1, 2, 3]); // 正确,数组有 length 属性 loggingIdentity(42); // 错误,数字没有 length 属性
- 有时你可能希望泛型类型满足某些条件。你可以使用
-
泛型工具类型:
- TypeScript 提供了一些内置的泛型工具类型,如
Partial<T>
、Readonly<T>
、Record<K, T>
等,这些工具类型可以帮助你更方便地操作类型。
interface User { name: string; age: number; } type PartialUser = Partial<User>; // { name?: string; age?: number; } type ReadonlyUser = Readonly<User>; // { readonly name: string; readonly age: number; }
- TypeScript 提供了一些内置的泛型工具类型,如
-
泛型与联合类型:
- 泛型可以与联合类型结合使用,以处理多种可能的类型。
function merge<T, U>(obj1: T, obj2: U): T & U { return { ...obj1, ...obj2 }; } let result = merge({ name: "Alice" }, { age: 30 }); // { name: "Alice", age: 30 }
总结
泛型是 TypeScript 中一个非常强大的工具,它可以帮助你编写更加灵活和可重用的代码。通过使用泛型,你可以避免重复代码,并且能够在编译时捕获类型错误,从而提高代码的健壮性和可维护性。在实际开发中,泛型广泛应用于函数、接口、类以及工具类型中,是 TypeScript 类型系统中不可或缺的一部分。