<kbd id="5sdj3"></kbd>
<th id="5sdj3"></th>

  • <dd id="5sdj3"><form id="5sdj3"></form></dd>
    <td id="5sdj3"><form id="5sdj3"><big id="5sdj3"></big></form></td><del id="5sdj3"></del>

  • <dd id="5sdj3"></dd>
    <dfn id="5sdj3"></dfn>
  • <th id="5sdj3"></th>
    <tfoot id="5sdj3"><menuitem id="5sdj3"></menuitem></tfoot>

  • <td id="5sdj3"><form id="5sdj3"><menu id="5sdj3"></menu></form></td>
  • <kbd id="5sdj3"><form id="5sdj3"></form></kbd>

    理解TypeScript的泛型

    共 2174字,需瀏覽 5分鐘

     ·

    2021-03-29 12:43


    可以使用泛型來創(chuàng)建可重用的組件,一個組件可以支持多種類型的數據。這樣用戶就可以以自己的數據類型來使用組件。

    泛型函數

    // arg 參數類型是一個泛型變量 T,也可以使用不同的泛型參數名function identity<T>(arg: T): T {    return arg;}


    們定義了泛型函數后,可以用兩種方法使用。第一種是,傳入所有的參數,包含類型參數:

    let output = identity<string>("myString");  // type of output will be 'string'


    這里我們明確的指定了 Tstring 類型,并做為一個參數傳給函數,使用了<> 括起來而不是()。


    第二種方法更普遍。利用了類型推論 -- 即編譯器會根據傳入的參數自動地幫助我們確定T的類型:

    let output = identity("myString");  // type of output will be 'string'


    注意我們沒必要使用尖括號(<>)來明確地傳入類型;編譯器可以查看 myString 的值,然后把 T 設置為它的類型。類型推論幫助我們保持代碼精簡和高可讀性。如果編譯器不能夠自動地推斷出類型的話,只能像上面那樣明確的傳入 T 的類型,在一些復雜的情況下,這是可能出現(xiàn)的。


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

    泛型接口

    接口能夠描述 JavaScript 中對象擁有的各種各樣的外形。除了描述帶有屬性的普通對象外,接口也可以描述函數類型。


    為了使用接口表示函數類型,我們需要給接口定義一個調用簽名。它就像是一個只有參數列表和返回值類型的函數定義。參數列表里的每個參數都需要名字和類型。


    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;

    泛型類

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

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

    泛型約束

    我們有時候想操作某類型的一組值,并且我們知道這組值具有什么樣的屬性。在 loggingIdentity 例子中,我們想訪問 arg 的 length 屬性,但是編譯器并不能證明每種類型都有 length 屬性,所以就報錯了。


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


    相比于操作 any 所有類型,我們想要限制函數去處理任意帶有 .length 屬性的所有類型。只要傳入的類型有這個屬性,我們就允許,就是說至少包含這一屬性。為此,我們需要列出對于T的約束要求。


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


    interface Lengthwise {    length: number;}
    function loggingIdentity<T extends Lengthwise>(arg: T): T { console.log(arg.length); // Now we know it has a .length property, so no more error return arg;}


    瀏覽 50
    點贊
    評論
    收藏
    分享

    手機掃一掃分享

    分享
    舉報
    評論
    圖片
    表情
    推薦
    點贊
    評論
    收藏
    分享

    手機掃一掃分享

    分享
    舉報

    <kbd id="5sdj3"></kbd>
    <th id="5sdj3"></th>

  • <dd id="5sdj3"><form id="5sdj3"></form></dd>
    <td id="5sdj3"><form id="5sdj3"><big id="5sdj3"></big></form></td><del id="5sdj3"></del>

  • <dd id="5sdj3"></dd>
    <dfn id="5sdj3"></dfn>
  • <th id="5sdj3"></th>
    <tfoot id="5sdj3"><menuitem id="5sdj3"></menuitem></tfoot>

  • <td id="5sdj3"><form id="5sdj3"><menu id="5sdj3"></menu></form></td>
  • <kbd id="5sdj3"><form id="5sdj3"></form></kbd>
    jiujiuav | 亚洲aⅴ网站 | 亚洲福利在线免费观看 | 夜射夜啪成人一区 | 日韩欧美爱爱 |