1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        Typescript 類型的本質(zhì)是什么

        共 3795字,需瀏覽 8分鐘

         ·

        2021-08-20 00:38

        類型

        類型指的是變量的類型,而變量是一塊內(nèi)存空間,不同類型的變量會占用不同的字節(jié)數(shù),而且可以做的操作也不同。number、boolean、string 等類型的變量會占用不同的內(nèi)存大小。

        類型分為基礎(chǔ)類型和引用類型,基礎(chǔ)類型分配在棧上,而引用類型分配在堆上,之所以有引用類型是因為這種類型是復(fù)合出來的,比如對象,它可能有任意多個屬性,這種就放在可動態(tài)分配內(nèi)存的堆上,然后在棧上記錄下該地址,這就是引用類型。

        類型是運行時的變量的內(nèi)存空間大小和可以做的操作的標(biāo)識,但是代碼中不一定包含,根據(jù)代碼中是否有類型的標(biāo)識,語言分為了靜態(tài)類型語言和動態(tài)類型語言。

        靜態(tài)類型、動態(tài)類型、類型安全

        動態(tài)類型語言的代碼中沒有記錄變量的類型,對什么變量賦什么值做什么操作都是可以的,這樣寫代碼時不用考慮類型的問題,比較簡單,但是也有隱患,就是運行時變量賦值時發(fā)現(xiàn)類型不一致,或者調(diào)用了沒有的方法等,這是動態(tài)類型語言的缺點。

        靜態(tài)類型語言則是把類型的標(biāo)識保存在了代碼里,也就是有靜態(tài)類型系統(tǒng)。聲明的變量的類型在運行時會分配相應(yīng)的內(nèi)存空間,就會賦相同類型的值,就會調(diào)用該類型有的方法,如果不是,在編譯時就能檢查出來。

        這種同樣類型的變量只賦值同類型的值,只做該類型允許的操作就叫做類型安全,顯然,動態(tài)類型是類型不安全的,會在運行時有各種類型相關(guān)問題,而靜態(tài)類型則通過類型系統(tǒng)在編譯期間就把類型不安全的操作檢查了出來進(jìn)行報錯,所以是類型安全的。

        typescript 就是給動態(tài)類型的 javascript 添加了一套靜態(tài)類型系統(tǒng),是 javascript 的超集。

        靜態(tài)類型系統(tǒng)的 3 個層次

        其實靜態(tài)類型系統(tǒng)分為 3 個層次:

        純靜態(tài)的類型系統(tǒng)

        第一種就是純靜態(tài)的類型系統(tǒng),變量的類型都是定義時聲明的,但有一個問題就是遇到參數(shù)的類型可能是多種類型的時候會比較麻煩。一些古老的語言是這種。

        比如:

        int add(int a, int b) {
            return a + b;
        }
        double add(double a, double b) {
            return a + b;
        }

        帶泛型的靜態(tài)類型系統(tǒng)

        第二種是帶泛型的靜態(tài)類型系統(tǒng),泛型也叫類型參數(shù),具體的類型可以通過泛型參數(shù)來動態(tài)確定,多了一定的靈活性。java 是這種。

        比如:

        T add<T>(T a, T b) {
            return a + b;
        }

        支持高級類型的靜態(tài)類型系統(tǒng)

        第三種是支持高級類型的靜態(tài)類型系統(tǒng),高級類型就是生成類型的類型,它除了可以傳泛型參數(shù)外還可以支持分支、遞歸、取屬性等操作,可以通過復(fù)雜的邏輯來生成類型。typescript 是這種。

        比如下面的高級類型:

        type RepeatN<Item, N extends number, Tuple extends any[] = []> = Tuple['length'extends N ? Tuple : RepeatN<Item, N, [...Tuple, Item]>;

        它的作用是當(dāng)傳入泛型參數(shù)時,返回該參數(shù)重復(fù) n 次的元組:

        type res = RepeactN<'a', 3>;
        // res 為 ['a''a''a']

        高級類型支持類型編程,甚至是圖靈完備的,圖靈完備的意思就是說提供的語言特性可以描述所有可計算的邏輯。也就是所有用 javascript 寫的邏輯在 typescript 中用類型都可以實現(xiàn),只不過具體語法有不同。

        高級類型示例

        就拿上面這個把參數(shù)重復(fù) n 次的代碼來說,如果用 javascript 我們會這樣寫:

        function repeactN(item, n{
            const res = [];
            for (let i = 0; i< n; i++) {
                res[i] = item;
            }
            return res;
        }

        用 typescript 的類型系統(tǒng)怎么寫呢?

        圖靈完備意味著兩者都能實現(xiàn)同樣的邏輯,只不過實現(xiàn)方式不同。我們只要把邏輯想清楚,然后用類型支持的語法實現(xiàn)即可。

        首先,函數(shù)參數(shù)在 ts 類型里就是泛型參數(shù),變量在 ts 類型里也用泛型參數(shù)來存儲,循環(huán)在 ts 類型利用遞歸來實現(xiàn),所以就是這樣的:

        首先定義類型,Item 是重復(fù)的目標(biāo), n 是個數(shù),然后第三個參數(shù) Tuple 用來存儲結(jié)果

        type RepeatN<Item, N extends number, Tuple extends any[] = []>

        然后具體的實現(xiàn)就是要不斷的往 Tuple 里放 Item,遞歸構(gòu)造

        RepeatN<Item, N, [...Tuple, Item]>

        直到 Tuple 的 length 到了 N

        Tuple['length'] extends N ? Tuple : RepeatN<Item, N, [...Tuple, Item]>;

        所以,完整的類型就是這樣的:

        type RepeatN<Item, N extends number, Tuple extends any[] = []> = Tuple['length'extends N ? Tuple : RepeatN<Item, N, [...Tuple, Item]>;

        通過這個高級類型我們可以感受到,typescript 的靜態(tài)類型系統(tǒng)就是第三種,可以支持類型編程,可以實現(xiàn)各種復(fù)雜邏輯,最終生成目標(biāo)類型。

        tyepscript 類型系統(tǒng)復(fù)雜度的原因

        為什么 tyepscript 要設(shè)計這么復(fù)雜的類型系統(tǒng)呢?

        靜態(tài)類型的目的就是把運行時的行為在編譯時就檢查出來,那么就要在編譯期間就要確定最終類型,而 javascript 邏輯又很靈活,所以想還沒運行就確定類型就需要各種類型的推導(dǎo)來生成最終類型,所以也就設(shè)計出了帶高級類型的靜態(tài)類型系統(tǒng)。

        tyepscript 靜態(tài)類型系統(tǒng)的復(fù)雜度主要是因為 javascript 比較靈活導(dǎo)致的,是不可避免的。

        總結(jié)

        類型本質(zhì)上是運行時變量的內(nèi)存大小和可對它進(jìn)行的操作,變量只賦值同類型的值就是類型安全動態(tài)類型在源碼中沒有類型信息,沒法保證類型安全,而靜態(tài)類型則是在源碼中有類型信息,可以在編譯期間檢查出類型的錯誤,保證類型安全。

        javascript 就是動態(tài)類型語言,雖然寫代碼比較簡單,但是運行時很容易出類型安全問題,typescript 就是解決了 javascript 沒有靜態(tài)類型系統(tǒng)的問題而做的擴展。ts 的類型系統(tǒng)是支持泛型、支持高級類型的靜態(tài)類型系統(tǒng),而且類型的語法是圖靈完備的,也就是各種邏輯都可以表達(dá),只不過和 js 中的語法會有不同。這也是 ts 給 js 擴展的這套類型系統(tǒng)中最復(fù)雜的部分,被大家戲稱為類型體操,但是這種復(fù)雜度是為了讓 javascript 變得類型安全不可避免的。

        其實高級類型的所謂類型體操也沒有那么難,只要想清楚要表達(dá)的邏輯,然后一步步用相應(yīng)的語法實現(xiàn)即可,只不過語法會有一些別扭,比如變量用泛型參數(shù)實現(xiàn)、循環(huán)用遞歸實現(xiàn)等,但只要理清邏輯,實現(xiàn)起來還是不難的。

        瀏覽 56
        點贊
        評論
        收藏
        分享

        手機掃一掃分享

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

        手機掃一掃分享

        分享
        舉報
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            颐和园床戏裸戏视频 | 舒淇操逼视频 | 欧美裸体tickle免费网站 | 美女骚逼 | 欧美亚洲一区 | 装修工人把我压在茶几的背景故事 | 免费看靠逼视频 | 91久久精品國產亞洲 | 欧美特黄三级 | 亚洲免费毛片视频 |