TypeScript入門-泛型


泛型

要創建一個可重用的組件,其中的數據類型就必須要兼容很多的類型,那么如何兼容呢,TypeScript提供了一個很好的方法:泛型

 

Hello World

要兼容多種數據格式,可能會有人想到any,即

function identify(arg: any): any{
    return arg;
}

 

使用any存在一個問題,有可能傳入的值和返回的值不是同一種值,例如,傳入數字,但是不確定返回的是什么值

要解決這個問題,我們需要引入類型變量-一種特殊的變量,只用於表示類型不表示值

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

 

給identify添加了類型變量T,用來捕獲傳入值的類型,然后將返回值的類型也設置為T,就實現了傳入值和返回值為同一類型值的需求

我們把identify這個函數叫做泛型,因為它適用於所有類型,並且不會有any類型存在的問題

使用泛型的方法有兩種:

  1、傳入所有的參數,包括類型參數

let output = identify<string>('qwe');

 

  2、利用類型推論--即編譯器會根據傳入的參數自動地幫助我們確定T的類型

let output = identify('qwe');

 

泛型變量

在泛型中,我們要合理正確的使用泛型變量T,要牢記T表示任何類型

錯誤使用:

function identify<T>(arg: T): T {
    console.log(arg.length);// Error: T doesn't have .length
    return arg;
}

 

在泛型中我們使用了length這個屬性,但是T代表任何類型,所以有可能是number,而number是沒有length屬性的,所以會報錯

如果想要使用length這個屬性,我們可以創建數組

function identify<T>(arg: T[]): T[] {
    console.log(arg.length);// Error: T doesn't have .length
    return arg;
}

 

泛型類型

泛型函數的類型與非泛型函數的類型沒什么不同,只是有一個類型參數在最前面,像函數聲明一樣:

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

let myIdentify: <U>(arg: U) => U = identify;

從上面的代碼中可以看出也可以使用不同的泛型參數名,只要在數量上和使用方式上能對應上就可以

 

當然也可以把泛型參數當做一個接口的參數,這樣就可以知道這個接口具體用的是那種類型

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

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

let myGenericidentify: GenericIdnetify<string> = identity;

 

泛型類

泛型類看上去與泛型接口差不多。 泛型類使用( <>)括起泛型類型,跟在類名后面。

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; };

 

泛型約束

在前面的泛型變量中遇到了一個問題,就是在泛型中調用參數的length時,如果參數沒有Length屬性會報錯,而使用泛型約束,就是只有滿足一定的條件才可以使用這個泛型

為此,我們定義一個接口來描述約束條件。 創建一個包含 .length屬性的接口,使用這個接口和extends關鍵字還實現約束:

interface lengthwise{
    length: number;
}

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

identity(123); //error

identity('qwe'); //true

當傳入123時,沒有length屬性,就報錯,而傳入字符串qwe時則完全正確

 

參考資料:

        TypeScript中文網 · TypeScript——JavaScript的超集


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM