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泛型内容请搜索阿兔在线工具以前的文章或继续浏览下面的相关文章希望大家以后多多支持阿兔在线工具!