【TypeScript】泛型

2021/09/09 09:35:17

泛型其实就是类型的函数。

摘要

  1. 泛型函数的类型与非泛型函数的类型没什么不同,只是有一个类型参数在最前面。
  2. 泛型类指的是实例部分的类型,所以类的静态属性不能使用这个泛型类型。
  3. 加了约束的泛型不再适用于任何类型。
  4. 可以同时存在多个类型变量。

泛型函数

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

定义通用函数,可以适配不同的类型

使用类型变量定义泛型函数

注意 T 不是必须的类型变量名,只要在数量和使用方式上对应就行。

function identity<T>(arg: T): T => arg;

function identity2<T>(arg: T[]): T[] => arg;

在接口中实现泛型类

  • 在接口中定义泛型函数
interface GenericIdentityFn {
  <T>(arg: T): T;
}

function identity<T>(arg: T): T {
  return arg;
}

let myIdentity: GenericIdentityFn = identity;
  • 定义一个泛型接口
interface GenericIdentityFn<T> {
  (arg: T): T;
}

function identity<T>(arg: T): T {
  return arg;
}

let myIdentity: GenericIdentityFn<number> = identity;

调用泛型函数

  • 传入所有参数,包括类型参数
let output = identity < string > "myString"; // type of output will be 'string'
  • 不传类型参数,ts 进行类型推断
let output = identity("myString"); // type of output will be 'string'

泛型类

泛型类指的是实例部分的类型,所以类的静态属性不能使用这个泛型类型。

class GenericNumber<T> {
    zeroValue: T;
    add: (x: T, y: T) => T;
}

let myGenericNumber = new GenericNumber<number>();
myGenericNumber.zeroValue = 0;
myGenericNumber.add = function(x, y) { return x + y; };

泛型接口

用泛型接口实现泛型函数

interface GenericIdentityFn<T> {
  (arg: T): T;
}

function identity<T>(arg: T): T {
  return arg;
}

let myIdentity: GenericIdentityFn<number> = identity;

用泛型接口实现泛型类

interface GenericIdentityFn<T> {
  age: T;
}

class A implements GenericIdentityFn<number> {
  age = 1;
}

泛型类型别名

type Container<T> = { value: T };

泛型约束

对泛型的类型进行约束,下面例子中的 loggingIdentity 函数不再适用于任意类型。

interface Lengthwise {
    length: number;
}

function loggingIdentity<T extends Lengthwise>(arg: T): T {
    console.log(arg.length);
    return arg;
}

loggingIdentity({length: 1});