TypeScript 泛型接口、泛型函数、泛型类

泛型(Generics)是指在定义函数、接口或类的时候,不预先指定具体的类型,而在使用的时候再指定类型的一种特性。使用泛型,通常有三种情况:泛型接口,泛型函数,泛型类,如下文所述。

1、泛型接口

接口既可以在面向对象编程中表示为行为的抽象,也可以用来描述对象的形状。声明泛型接口定义接口的时候也可以指定泛型,如下所示:声明一个名为 Identity 的简单接口,该接口具有两个属性(value 和 message)和两个用作属性类型的泛型类型变量(T 和 U)。

  • interface Identity<T, U> {
  • value: T;
  • message: U;
  • }

使用 Identity 接口作为对象类型来声明两个变量。

  • let myNumber: Identity<number, string> = {
  • value: 25,
  • message: 'Hello!'
  • }
  • let myString: Identity<string, number> = {
  • value: 'Hello!',
  • message: 25
  • }

2、泛型函数:将泛型接口声明为函数类型

声明一个名为 ProcessIdentity 的泛型接口,该接口包含方法的泛型签名 (value: T, message: U): T。 请注意,该方法没有名称。通过执行此操作,可以将其应用于具有匹配的类型签名的任何函数。

  • interface ProcessIdentity<T, U> {
  • (value: T, message: U): T;
  • }

声明一个名为 processIdentity 的函数,该函数具有与 ProcessIdentity 接口相同的类型签名。

  • function processIdentity<T, U> (value: T, message: U) : T {
  • console.log(message);
  • return value
  • }

声明一个名为 processor 的函数类型变量,以 ProcessIdentity 接口作为变量类型,传递 number 作为 T 类型,string 作为 U 类型。 然后,将 processIdentity 函数分配给它。 现在,你可以将此变量用作代码中的函数,TypeScript 将验证这些类型。

  • let processor: ProcessIdentity<number, string> = processIdentity;
  • let myNumber = processor(100, 'Hello!'); // OK
  • let myString = processor('Hello!', 100); // Type check error

3、泛型类:将泛型接口声明为类类型

声明一个名为 ProcessIdentity 的接口,该接口具有两个属性(value 和 message)和两个用作属性类型的泛型类型变量(T 和 U)。然后,添加方法 process 的一个泛型签名,该方法返回 T 类型的值。

  • interface ProcessIdentity<T, U> {
  • value: T;
  • message: U;
  • process(): T;
  • }

定义一个实现 ProcessIdentity 接口的名为 processIdentity 的泛型类。在这种情况下,请在 processIdentity 类 X 和 Y 中命名变量类型。可以在接口和类中使用不同的变量名称,因为类型值沿链向上传播,而变量名称并不重要。

  • class processIdentity<X, Y> implements ProcessIdentity<X, Y> {
  • value: X;
  • message: Y;
  • constructor(val: X, msg: Y) {
  • this.value = val;
  • this.message = msg;
  • }
  • process() : X {
  • console.log(this.message);
  • return this.value
  • }
  • }

声明一个新变量并向其分配新的 processIdentity 对象,传入 number 和 string 作为 X 和 Y 变量类型,传入 number 和 string 作为参数值。

  • let processor = new processIdentity<number, string>(100, 'Hello');
  • processor.process(); // Displays 'Hello'
  • processor.value = '100'; // Type check error

4、直接定义泛型类

还可以声明没有接口的泛型类。 此示例将 processIdentity 声明为泛型类,但没有实现 ProcessIdentity 接口。

  • class processIdentity<T, U> {
  • private _value: T;
  • private _message: U;
  • constructor(value: T, message: U) {
  • this._value = value;
  • this._message = message;
  • }
  • getIdentity() : T {
  • console.log(this._message);
  • return this._value
  • }
  • }
  • let processor = new processIdentity<number, string>(100, 'Hello');
  • processor.getIdentity(); // Displays 'Hello'