基本

泛型:<>在名字后
类型断言: <>在名字前

写法

  1. // 定义
  2. function 函数名<T> (param1: string, param2: T): Array<T> {
  3. let result: T[] = [];
  4. // ...
  5. return result;
  6. }
  7. let 函数名 = function<T> (param1: string, param2: T): Array<T> {}
  8. // 调用
  9. 函数名<number>();

extends

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

一个或多个类型参数

  1. // 第2个参数用了泛型
  2. function createArray<T>(length: number, value: T): Array<T> {
  3. let result: T[] = [];
  4. for (let i = 0; i < length; i++) {
  5. result[i] = value;
  6. }
  7. return result;
  8. }
  9. createArray<string>(3, 'x'); // ['x', 'x', 'x']
  10. createArray(3, 'x'); // ['x', 'x', 'x'] 用了类型推断

泛型约束

我们使用了 extends 约束了泛型 T 必须符合接口 Lengthwise 的形状,也就是必须包含 length 属性。

  1. interface Lengthwise {
  2. length: number;
  3. }
  4. function loggingIdentity<T extends Lengthwise>(arg: T): T {
  5. console.log(arg.length);
  6. return arg;
  7. }

应用:
image.png
多个泛型相互约束

  1. function copyFields<T extends U, U>(target: T, source: U): T {
  2. for (let id in source) {
  3. // 这里是类型断言为T类型,只出现T含有的id
  4. // 试想如果source有个e: 30,<T>source就不会出现e
  5. target[id] = (<T>source)[id];
  6. }
  7. return target;
  8. }
  9. let x = { a: 1, b: 2, c: 3, d: 4 };
  10. copyFields(x, { b: 10, d: 20 });

泛型接口

  1. interface CreateArrayFunc {
  2. <T>(length: number, value: T): Array<T>;
  3. }
  4. let createArray: CreateArrayFunc;
  1. interface CreateArrayFunc<T> {
  2. (length: number, value: T): Array<T>;
  3. }
  4. // 注意,此时在使用泛型接口的时候,需要定义泛型的类型
  5. let createArray: CreateArrayFunc<any>;
  1. createArray = function<T>(length: number, value: T): Array<T> {
  2. }

泛型类

  1. class GenericNumber<T> {
  2. zeroValue: T;
  3. add: (x: T, y: T) => T;
  4. }
  5. // 实例化的时候,传入number类型
  6. let myGenericNumber = new GenericNumber<number>();
  7. myGenericNumber.zeroValue = 0;
  8. myGenericNumber.add = function(x, y) { return x + y; };

泛型参数的默认类型

  1. function createArray<T = string>(length: number, value: T): Array<T> {
  2. }