本文深入解析 TypeScript 泛型的核心概念,阐述如何通过类型变量实现参数化类型。详细演示泛型方法、泛型类及泛型接口的定义与使用技巧,对比非泛型与泛型实现的差异,帮助开发者在保持类型安全的同时提升代码复用性。
1 什么是泛型
泛型的本质在于参数化类型,即操作的数据类型被指定为一个参数。这种参数化机制可应用于类、接口和方法的创建中,分别对应泛型类、泛型接口和泛型方法。

泛型通过<T>来定义类型,<T>中的 T 可以是 U 或其他合法字母,通常建议采用大写字母。泛型可视为一种不确定的单独类型,在函数中使用泛型能够约束参数与返回值的类型保持一致。
2 泛型方法
在定义 identity 函数时,该函数旨在返回传入的任何值。若不使用泛型,函数定义可能如下所示:
function identity(arg: number): number {
return arg;
}
然而,这种方式强制要求参数和返回值必须为 number 类型。若类型不确定,我们可能会尝试使用 any 类型来定义函数:
function identity(arg: any): any {
return arg;
}
但使用 any 类型会导致函数接收任意类型的 arg 参数,从而丢失关键信息:传入类型与返回类型应当相同。例如,若传入数字,却可能返回任意类型的值。
为解决此问题,可使用类型变量。类型变量是一种特殊变量,仅用于表示类型而非具体值。其语法格式为:
function 函数名<T>(参数: T): T {
return 值;
}
示例代码:
function identity<T>(arg: T): T {
return arg;
}
为 identity 添加类型变量 T。T 用于捕获用户传入的类型(如 number),随后即可使用该类型。再次使用 T 作为返回值类型,从而确保参数类型与返回值类型一致,允许跟踪函数内使用的类型信息。
定义泛型方法后,可通过两种方式使用。
// 第一种:传入所有的参数,包含类型参数
var a = identity<string>("myString");
// 第二种:使用类型推论——即编译器会根据传入的参数自动地帮助我们确定T的类型
var a = identity("myString");3 泛型类
当需要实现寻找最小值的算法,且需同时支持返回数字和字符串类型时,可通过类的泛型来实现。
示例代码:非泛型实现方式
class MinClass {
list: number[] = [];
add(num: number) {
this.list.push(num);
}
min(): number {
var minNum = this.list[0];
for (var i = 0; i < this.list.length; i++) {
if (minNum > this.list[i]) {
minNum = this.list[i];
}
}
return minNum;
}
}示例代码:泛型方式实现
class MinClass<T> {
list: T[] = [];
add(num: T) {
this.list.push(num);
}
min(): T {
var minNum = this.list[0];
for (var i = 0; i < this.list.length; i++) {
if (minNum > this.list[i]) {
minNum = this.list[i];
}
}
return minNum;
}
}4 泛型接口
首先查看普通函数接口:
interface ConfigFn { // 普通函数接口
(value1: string, value2: string): string;
}
将其转换为泛型接口有两种方法:
1、第一种定义方式
interface ConfigFn {
<T>(value: T): T; // T表示参数类型
}
2、第二种方式
interface ConfigFn<T> {
(value: T): T; // T表示参数类型
}
到此这篇关于TypeScript泛型使用详细介绍的文章就介绍到这了,更多相关TypeScript泛型内容请搜索本站以前的文章或继续浏览下面的相关文章希望大家以后多多支持本站!