泛型(Generics)是指在定义函数、接口或类的时候,不预先指定具体的类型,而在使用的时候再指定类型的一种特性。

我们需要一种方式使返回值的类型与传入参数的类型是相同的。这里,我们使用了类型变量,它是一种特殊的变量,只用于表示类型而不是值。

  1. function identity<T>(arg: T): T {
  2. return arg;
  3. }

泛型函数

泛型函数的类型与非泛型函数的类型没什么不同,只是有一个类型参数在最前面,像函数声明一样。

  1. function identity<T>(arg: T): T {
  2. return arg;
  3. }
  4. let myIdentity: { <T>(arg: T): T } = identity;

要想使用定义的泛型函数,有两种方式。
第一种:传入所有的参数,包含类型参数:

  1. let output = identity<string>("myString");

第二种,利用类型推论——即编译器会根据传入的参数自动地帮助我们确定 T 的类型

  1. let output = identity("myString");

泛型函数接口

可以使用含有泛型的接口来定义函数的形状。还可以把泛型参数提前到接口名上,注意,此时再使用泛型接口的时候,需要定义泛型的类型。

  1. interface ConfigFn {
  2. <T>(value: T): T;
  3. }
  4. var getData: ConfigFn = function<T>(value: T): T {
  5. return value;
  6. };
  7. getData<string>("hh");
  8. // 另一种写法:
  9. interface ConfigFn<T> {
  10. (value: T): T;
  11. }
  12. function getData<T>(value: T) {
  13. return value;
  14. }
  15. var myGetData: ConfigFn<string> = getData;

泛型类

泛型可以用于类的类型定义中。它既可以作用于类本身,也可以作用于类的成员函数。

  • 泛型类看上去与泛型接口差不多。泛型类使用(<>)括起来泛型类型,跟在类名后面。
  • 泛型类指的是实例部分的类型,所以类的静态属性不能使用这个泛型类型。

注意:无法创建泛型枚举和泛型命名空间。