TypeScript學習7:泛型

爲何引入泛型

若是說接口和類是對一類事物的抽象描述,那麼泛型能夠說是對一類數據的抽象描述,進一步增強了語言的抽象程度,讓組件重用性更好。 typescript

看一個小例子,實現數組的單條數據插入:數組

function insertTo<T>(array: T[], index: number, t: T): T[] {
  if (index < 0 || array.length - 1 < index) {
    throw new Error('Illegal index.');
  }
  array.splice(index, 0, t);
  return array;
}

const arr1 = [1, 2, 4];
insertTo(arr1, 2, 3);
console.log(arr1);

const arr2 = ['a', 'b', 'd'];
insertTo(arr2, 2, 'c');
console.log(arr2);

這個函數使用了泛型來表示傳入參數的類型,咱們能夠很明顯感受到泛型的好處:一個函數就能夠適配多種類型。用普通方式,咱們要重複這段邏輯寫n個函數,用泛型一個就夠用,這就是抽象的好處。函數

泛型的不一樣場景

泛型能夠用於函數,也能夠用於類,還有更高級的用法:帶限定的泛型。後面高級類型,還會用到泛型,會更復雜一些。學習

泛型函數

上面已給了一個例子,這裏再補充一個用法,限定類型的泛型函數:this

interface GenericInsertFn<T> {
    <T>(array: T[], index: number, t: T): T[]
}

let myInsertTo: GenericInsertFn<number> = insertTo;

經過類型限定以後,咱們就獲得了一個新的函數,這個函數只能操做數字類型的數組。code

泛型類

泛型類和泛型函數用法相似,只是泛型聲明在類上,整個類範圍均可以用。
看個小例子:接口

class MyArrayList<T> {
  private _array: T[];

  constructor() {
    this._array = [];
  }

  get lenght(): number {
    return this._array.length;
  }

  get(index: number): T {
    if (index < 0 || this._array.length - 1 < index) {
      throw new Error('Illegal index.');
    }
    return this._array[index];
  }

  push(...elements: T[]): number {
    return this._array.push(...elements);
  }

  insertTo(index: number, t: T): T[] {
    if (index < 0 || this._array.length - 1 < index) {
      throw new Error('Illegal index.');
    }
    this._array.splice(index, 0, t);
    return this._array;
  }
}

以上例子實現了一個簡單的泛型的ArrayList,若是你熟悉Java語言,對此就不陌生了。實現的效果和函數相似,也是抽象和重用。ip

泛型的限定

有的場景,泛型須要限定範圍,好比一個任務執行者函數,須要接受實現了工做者接口的函數做爲參數才能夠執行,那麼就須要帶限定的泛型參數,看代碼:element

interface IWorker {
  (task: string): number; 
}

function excutor<W extends IWorker>(r: W) {
  r('case1');
}

const myWorker: IWorker = function (task: string) {
  console.log(`${task} is start.`);
  return 1;
}

excutor(myWorker);

再看一個更復雜一點的用法,多重泛型,抽象度也更高,通用性也更好。get

interface IJobRunner<T, K> {
  run(t: T): K;
}

interface ITimeJobExcutor<T, K, R extends IJobRunner<T, K>> {
  excute(r: R): void;
}

基本的泛型用法學習完了,後面高級類型還會繼續學習更高級的用法。

相關文章
相關標籤/搜索