Typescript 泛型

82 阅读1分钟

软件工程中,我们不仅要创建一致的定义良好的API,同时也要考虑可重用性。

组件不仅能够支持当前的数据类型,同时也能支持未来的数据类型,这在创建大型系统时为你提供了十分灵活的功能。

泛型(Generics),从字面上理解,泛型就是一般的,广泛的。

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

泛型中的 T 就像一个占位符、或者说一个变量,在使用的时候可以把定义的类型像参数一样传入,它可以原封不动地输出

泛型在成员之间提供有意义的约束,这些成员可以是:函数参数、函数返回值、类的实例成员、类的方法等。

泛型基本使用

function echo<T>(arg: T): T {
  return arg;
}
const result = echo(true);

交换数组位置

function swap<T, U>(tuple: [T, U]): [U, T] {
  return [tuple[1], tuple[0]];
}
const result = swap(["string", 123]);

使用泛型变量

function echoWithArr<T>(arg: T[]): T[] {
  console.log(arg.length);
  return arg;
}

const arr = echoWithArr([1, 2, 3]);
// const string = echoWithArr(123)

泛型约束

interface IWithLength {
  length: number;
}

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

const str = echoWithLength("str");
const obj = echoWithLength({ length: 10, width: 10 });
const arr = echoWithLength([1, 2, 3]);

队列

class Queue<T> {
  private data: T[] = [];
  push(item: T) {
    return this.data.push(item);
  }
  pop(): T | undefined {
    return this.data.shift();
  }
}

const queue = new Queue<number>();
queue.push(1);
console.log(queue.pop()?.toFixed()); // 1

const queue2 = new Queue<string>();
queue2.push("sunshine");
console.log(queue2.pop()?.length); // 8

泛型类型

interface KeyPair<T, U> {
  key: T;
  value: U;
}

let kp1: KeyPair<number, string> = { key: 123, value: "str" };
let kp2: KeyPair<string, number> = { key: "age", value: 99 };

let arr: number[] = [1, 2, 3];
let arrTwo: Array<number> = [1, 2, 3];

interface IPlus<T> {
  (a: T, b: T): T;
}

function puls(a: number, b: number): number {
  return a + b;
}
function connent(a: string, b: string): string {
  return a + b;
}
const a: IPlus<number> = puls;
const b: IPlus<string> = connent;