泛型(Generics)是指在定义函数、接口或类的时候,不预先指定具体的类型,而在使用的时候再指定类型的一种特性。
我们需要一种方式使返回值的类型与传入参数的类型是相同的。这里,我们使用了类型变量,它是一种特殊的变量,只用于表示类型而不是值。
function identity<T>(arg: T): T {
return arg;
}
泛型函数
泛型函数的类型与非泛型函数的类型没什么不同,只是有一个类型参数在最前面,像函数声明一样。
function identity<T>(arg: T): T {
return arg;
}
let myIdentity: { <T>(arg: T): T } = identity;
要想使用定义的泛型函数,有两种方式。
第一种:传入所有的参数,包含类型参数:
let output = identity<string>("myString");
第二种,利用类型推论——即编译器会根据传入的参数自动地帮助我们确定 T 的类型
let output = identity("myString");
泛型函数接口
可以使用含有泛型的接口来定义函数的形状。还可以把泛型参数提前到接口名上,注意,此时再使用泛型接口的时候,需要定义泛型的类型。
interface ConfigFn {
<T>(value: T): T;
}
var getData: ConfigFn = function<T>(value: T): T {
return value;
};
getData<string>("hh");
// 另一种写法:
interface ConfigFn<T> {
(value: T): T;
}
function getData<T>(value: T) {
return value;
}
var myGetData: ConfigFn<string> = getData;
泛型类
泛型可以用于类的类型定义中。它既可以作用于类本身,也可以作用于类的成员函数。
- 泛型类看上去与泛型接口差不多。泛型类使用(
<>
)括起来泛型类型,跟在类名后面。 - 泛型类指的是实例部分的类型,所以类的静态属性不能使用这个泛型类型。
注意:无法创建泛型枚举和泛型命名空间。