TypeScript 的范型(Generics)是一种创建可重复使用的组件的方式,这种组件可以对多种数据类型进行操作。
范型本质上是为参数化的类型系统提供了工具,它提供了一种方法,能让你在定义函数、接口或类时不具体指定类型,而是在使用时再明确类型。
普通类型和范型最主要的区别
范型在函数、接口以及类中都可以应用。以下以一个函数为例:
function getArgs<T>(arg: T): T {
return arg;
}
在此代码中,我们定义了一个名为 “getArgs” 的函数,接收一个类型为 “T” 的参数,并将这个参数直接返回。
类型 “T” 就是我们设定的范型,当使用这个函数的时候,就可以确定 “T” 的具体类型:
typescript复制代码
let output = getArgs<string>("hello"); // 类型设置为 string
console.log(output); // 打印:hello
范型的一大用途是创建可复用的组件。例如,我们可以用范型实现一个具有前后两个元素之间有序关系的链表:
class LinkedList<T> {
private data: T[] = [];
constructor(private compareFunc: (a: T, b: T) => number) {}
add(item: T) {
let index = this.data.length;
while (index > 0 && this.compareFunc(this.data[index - 1], item) > 0) {
this.data[index] = this.data[index - 1];
index--;
}
this.data[index] = item;
}
get(index: number): T {
return this.data[index];
}
}
在此代码中,**LinkedList
**类就可以针对任何具有顺序关系的类型进行操作。
为了提高读者对范型的理解和熟练程度,这里附上了两道实战题目和答案:
题目1
实现一个范型函数,能够取出一个数组中的最小值。假设数组中的元素是可以直接比较大小的。
function minItem<T>(arr: T[]): T {
return arr.reduce((prev, curr) => prev < curr ? prev : curr);
}
题目2
基于**LinkedList
**类,实现一个字符链表类?CharLinkedList
,字符的顺序关系由字母表决定。
class CharLinkedList extends LinkedList<string> {
constructor() {
super((a, b) => a.localeCompare(b));
}
}
总范型是 TypeScript 中的一个重要特性,作为 TypeScript 强大类型系统的一部分,它大大提升了代码的灵活性和安全性。
范型的主要优点在于其灵活性和高效性。通过范型,您可以避免因类型转换而引起的额外运算负担,并且通过类型检查,增强了代码的稳定性和健壮性。