一文學會 TypeScript 的 82% 經常使用知識點(上)

一文學會 TypeScript 的 82% 經常使用知識點(上)

前端專欄 2019-11-22 19:17:55
一文學會 TypeScript 的 82% 經常使用知識點(上)

 

對於前端從業者來講,TypeScript(如下簡稱 TS)已經不算是新技術。前端

Vue3 的源碼基於 TS 編寫, Angular 項目默認支持 TS 等。它出現的頻率愈來愈高,而學習難度並不大,大概一個週末能夠熟悉。數組

投入少,產出大,因此最好仍是花點時間學習一下。函數

本文根據 TS handbook 整理出 TS 關鍵的知識點,並對某些部分做了擴展,但願能幫助你們學習理解。學習

前言

在學習 TS 以前,須要理解它的兩個特色:prototype

  1. TS 是 JS 的超集
  2. TS 給 JS 帶來類型系統

這意味着 TS 的根基是 JS,是在 JS 的 基礎上添加了類型系統。3d

類型聲明對象

類型系統的一個特色是使用類型聲明。blog

一文學會 TypeScript 的 82% 經常使用知識點(上)

 

觀察上述代碼,在 JS 中,使用「等號=」給變量賦值。繼承

通過 TS 的擴展,可使用「冒號:」給變量賦類型。代碼中聲明變量 foo 的類型是 string。索引

類型校驗

類型系統的另外一個特色是進行類型校驗。

在 TS 中,須要校驗「等號=」左右的類型是否匹配。

一文學會 TypeScript 的 82% 經常使用知識點(上)

 

如上述代碼所示,值存在明確的類型,TS 會校驗左右兩側的類型是否匹配,若不匹配則提示錯誤。

在瞭解這些前置知識後,來看看具體的 TS 知識點。

1、基本類型

繼承 JS 的基本類型如:string、number、boolean、undefined、null。擴展了其餘基本類型如:any、never、void。

1.1 string

表示類型爲字符串

一文學會 TypeScript 的 82% 經常使用知識點(上)

 

1.2 number

表示類型爲數字

一文學會 TypeScript 的 82% 經常使用知識點(上)

 

1.3 boolean

表示類型爲布爾類型

一文學會 TypeScript 的 82% 經常使用知識點(上)

 

1.4 undefined

表示類型爲 undefined

一文學會 TypeScript 的 82% 經常使用知識點(上)

 

1.5 null

表示類型爲 null

一文學會 TypeScript 的 82% 經常使用知識點(上)

 

1.6 void

表示類型爲 undefined 或 null。

1.6.1 對於變量

一個聲明爲 void 類型的變量,只能被賦值爲 undefined 或 null。這種應用場景較少。

一文學會 TypeScript 的 82% 經常使用知識點(上)

 

1.6.2 對於函數

void 用於表示函數沒有返回值,只是執行某些操做。這是 void 的廣泛應用場景。

一文學會 TypeScript 的 82% 經常使用知識點(上)

 

一個沒有顯式返回的函數,默認 return undefined。符合 void 類型只能被賦值爲 undefined 或 null。

1.7 never

表示永遠不存在值。

典型例子:一個只會拋出異常的函數,它的返回值並不存在。

一文學會 TypeScript 的 82% 經常使用知識點(上)

 

執行函數則拋出錯誤,連 undefined 都不會返回。

1.8 any

表示可能爲任何類型。

典型例子:不肯定變量的類型或類型是動態的。

一文學會 TypeScript 的 82% 經常使用知識點(上)

 

2、引用類型

TS 中的引用類型,除了 JS 中的數組類型、對象類型,還擴展了枚舉類型,元祖類型。

2.1 數組類型

表示由某(些)類型組成的數組。有兩種寫法:方括號表示法和尖括號表示法。

2.1.1 方括號表示法

一文學會 TypeScript 的 82% 經常使用知識點(上)

 

表示 arr 的類型是由數字組成的數組。

2.1.2 尖括號表示法

使用 Array<元素類型>,這是數組泛型的使用形式,關於泛型後續會展開。

一文學會 TypeScript 的 82% 經常使用知識點(上)

 

2.2 只讀數組

使用 ReadonlyArray<屬性類型> 定義只讀數組。只讀數組只能在數組初始化時定義其值,建立後不能進行修改。

一文學會 TypeScript 的 82% 經常使用知識點(上)

 

只讀數組和常規數組類型 Array<T> 相似。區別在於:常規數組存在修改數組的方法,只讀數組不存在修改數組的方法。

2.3 object

表示類型爲對象。除了 string、number、bigint、boolean、 undefined、null、symbol 基本類型外的引用類型。

一文學會 TypeScript 的 82% 經常使用知識點(上)

 

2.4 元組

由定長數組構成,數組中的元素是某(些)類型。

一文學會 TypeScript 的 82% 經常使用知識點(上)

 

2.5 枚舉

使用關鍵字 enum 定義枚舉類型。默認枚舉值從 0 開始,能夠手動賦值。

一文學會 TypeScript 的 82% 經常使用知識點(上)

 

3、類型斷言

明確告訴 TS 某個值的類型。有兩種寫法:尖括號寫法、as 寫法。

尖括號寫法

一文學會 TypeScript 的 82% 經常使用知識點(上)

 

as 寫法

一文學會 TypeScript 的 82% 經常使用知識點(上)

 

注意事項

類型斷言和類型轉換是有明確區別,不能將它理解成類型轉換。

在闡述此注意事項以前,先引入另外一個概念:聯合類型。

一文學會 TypeScript 的 82% 經常使用知識點(上)

 

在上述代碼中,string | number 表示的就是一個聯合類型,意味着 answer 的類型能夠爲 string 或 number。

下面逐步解釋類型斷言和類型轉換之間的區別。

一文學會 TypeScript 的 82% 經常使用知識點(上)

 

上述代碼中,string | number 聯合類型包含 string 類型,因此這兩種類型之間存在聯繫。使用 as 將聯合類型斷言成更加具體的 string 類型。

一文學會 TypeScript 的 82% 經常使用知識點(上)

 

上述代碼中,將 number 類型斷言爲 string | number 類型。一樣是由於兩種類型之間存在聯繫,因此也容許斷言。至關於將一個具體的 number 類型斷言成更加普遍的聯合類型。

一文學會 TypeScript 的 82% 經常使用知識點(上)

 

而將 string 類型斷言爲 number 類型,這是兩種不一樣的類型,沒有任何聯繫,斷言會提示錯誤。

觀察上述三個例子,斷言發生在兩種類型存在聯繫的狀況,它並非將一種類型轉換成另外一種類型。

有些腦瓜子靈活的朋友會想到,藉助兩次斷言來進行相似的類型轉換。

一文學會 TypeScript 的 82% 經常使用知識點(上)

 

這是欺騙了 TS 校驗,後果只能本身承擔。

4、接口

上面提到使用 object 描述對象類型。可是,對於具備複雜結構的對象、函數。上述的 object 類型力有不逮。

一文學會 TypeScript 的 82% 經常使用知識點(上)

 

上述代碼中,即便是空對象,也能經過 object 類型校驗,而不會校驗對象的結構是否能知足後續使用。

此時,就須要使用接口。在 TS 中,接口是描述值的結構。

一文學會 TypeScript 的 82% 經常使用知識點(上)

 

上述代碼中,就定義了一個接口來描述參數 o,要求它是一個對象,含有 name 屬性,且屬性值是字符串。

因此,不符合此結構的空對象 {} 就提示錯誤。

通常來講,使用關鍵字 interface 來定義接口。

重寫上述接口 ——

一文學會 TypeScript 的 82% 經常使用知識點(上)

 

4.1 固定屬性

在接口中,使用 屬性名:屬性類型 的結構定義固定屬性。

一文學會 TypeScript 的 82% 經常使用知識點(上)

 

如上述代碼所示,傳入的對象須要具備 name 和 age 兩個屬性,不然會報錯。

4.2 可選屬性

在接口中,使用 屬性名?:屬性類型 的結構定義可選屬性。顧名思義,可選屬性能夠存在,也能夠不存在。

一文學會 TypeScript 的 82% 經常使用知識點(上)

 

4.3 只讀屬性

在接口中,使用 readonly 屬性名:屬性類型 的結構定義只讀屬性。只讀屬性只能在屬性初始化時定義其值,定義後不能進行修改。

一文學會 TypeScript 的 82% 經常使用知識點(上)

 

4.4 額外檢查

TS 會對對象字面量進行額外的屬性檢查。

一文學會 TypeScript 的 82% 經常使用知識點(上)

 

在上述代碼中,接口 Point 定義了兩個可選屬性,對象字面量中屬性 x 和接口兼容,屬性 z 是多餘無心義的。

雖然實際的屬性比接口定義的多,按照常規理解,這是能夠經過類型校驗,但事實卻相反。

TS 對於對象字面量是會進行額外的屬性檢查,體如今:

當對象字面量賦值給變量或它直接做爲參數傳遞給函數時,若是對象字面量的屬性沒有在接口中定義,則會報錯。

換句話說,對於對象字面量,當它直接賦值給變量和函數參數時,它的屬性不能比接口描述的多。

這裏重點是直接賦值,若是像例子中,先將對象字面量賦值給變量,再經過變量傳參,這樣間接的方法能夠繞過額外的檢查。

4.5 可索引類型

可索引類型包括字符串索引類型與數字索引類型。

4.5.1 字符串索引類型

字符串索引類型具備字符串索引簽名。

一文學會 TypeScript 的 82% 經常使用知識點(上)

 

4.5.2 數字索引類型

數字索引類型具備數字索引簽名

一文學會 TypeScript 的 82% 經常使用知識點(上)

 

4.5.3 混合索引簽名

屬性和索引簽名能夠造成混合索引簽名,可是屬性須要和索引簽名類型匹配。

一文學會 TypeScript 的 82% 經常使用知識點(上)

 

另外,TS 容許同時使用上述兩種簽名,可是數字索引返回值的類型,它必須是字符串索引返回值類型的子類型。

由於對於 JS 來講,當使用數字索引時,會將它轉換成字符串進行索引。因此它們須要保持一致。

一文學會 TypeScript 的 82% 經常使用知識點(上)

 

上述代碼中,ThreeD 是 TwoD 的子類型,因此接口 PointA 正確。

4.5.4 只讀索引簽名

能夠將索引簽名設置爲只讀,只能在數組初始化時定義其值,建立後不能進行修改。

一文學會 TypeScript 的 82% 經常使用知識點(上)

 

4.6 函數類型

函數類型具備調用簽名。

一文學會 TypeScript 的 82% 經常使用知識點(上)

 

如上述代碼所示,調用簽名包括參數列表和返回值類型。

對於函數類型來講,它校驗的值固然是函數 ——

一文學會 TypeScript 的 82% 經常使用知識點(上)

 

如上述代碼所示,函數的參數名能夠與簽名的參數名不一樣。關鍵是對應位置的參數類型須要相同。

4.7 類類型

這裏的概念有些複雜,若是有良好的 JS 基礎,會較易理解。

類的關鍵字是 Class,由 ES6 開始引入,並逐步完善。本質上 Class 屬於語法糖,是基於 prototype 原型鏈實現的。

一文學會 TypeScript 的 82% 經常使用知識點(上)

 

而不管是 ES5 或 ES6,屬性 age 是在建立的實例上,而方法 getAge() 是在實例的原型鏈上。

一文學會 TypeScript 的 82% 經常使用知識點(上)

 

而類自己,它是不存在 age 屬性 和 getAge() 方法的。

一文學會 TypeScript 的 82% 經常使用知識點(上)

 

固然,咱們也能夠給類自己定義屬性和方法。 但給類自己定義的屬性和方法並不能經過實例直接訪問。

一文學會 TypeScript 的 82% 經常使用知識點(上)

 

因此,類與實例的屬性和方法是割裂的。

TS 將描述類的屬性和方法部分稱爲類的靜態部分類型,將描述實例的屬性和方法部分稱爲類的實例部分類型。

一文學會 TypeScript 的 82% 經常使用知識點(上)

 

在上述代碼中,使用關鍵字 implements 描述類實現了接口。更準確的是:描述 類的實例部分 實現了接口。

實現該接口的類的實例,它是具備 age 屬性,getAge() 方法。而類自己(即類的靜態部分)具備何種屬性與方法,上述代碼沒有進行定義。

因此,這裏所說的類類型,其實是類(實例的)類型。

關於如何定義類的靜態部分的類型,在後續會詳細介紹。

4.8 接口繼承

接口的可使用關鍵字 extends 定義繼承。一個接口能夠繼承多個接口。

一文學會 TypeScript 的 82% 經常使用知識點(上)

 

4.9 混合類型

一個對象可能混合多種類型。

例如定義一個帶版本號的函數——

一文學會 TypeScript 的 82% 經常使用知識點(上)

 

值得注意,上述使用類型斷言,將函數斷言爲 Fn,即便 fn 在建立時並不存在 version 屬性。

4.10 接口繼承類

當接口繼承類類型時候,表如今繼承類的成員和結構,但不包括其實現。

接口繼承類的一個場景是,定義一個子類的類類型。

一文學會 TypeScript 的 82% 經常使用知識點(上)

 

結語

因爲文章篇幅問題,全文拆分紅上下兩篇發佈。

本篇主要介紹了 TS 的基本類型,引用類型、類型斷言、接口等知識點,瞭解上述的知識點能夠閱讀部分 TS 代碼。

下篇涉及函數、類、泛型等稍微複雜的知識點。

相關文章
相關標籤/搜索