成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

TypeScript 中 Interface 與 Type 的區別?該用哪個比較好?

開發 前端
類型別名的右邊可以是任何類型,包括基本類型、元祖、類型表達式( & 或 | 等);而在接口聲明中,右邊必須為變量結構。

[[415498]]

本文轉載自微信公眾號「三分鐘學前端」,作者sisterAn。轉載本文請聯系三分鐘學前端公眾號。

接口 與 類型別名 的異同點

相同點

1. 都可以描述對象或函數

  1. // 接口 
  2. interface Sister { 
  3.   name: string; 
  4.   age: number; 
  5.  
  6. interface SetSister { 
  7.   (name: string, age: number): void; 
  8.  
  9. // 類型別名 
  10. type Sister = { 
  11.   name: string; 
  12.   age: number; 
  13. }; 
  14.  
  15. type SetSister = (name: string, age: number) => void; 

2. 都可以擴展

interface 和 type 可以混合擴展,也就是說 interface 可以擴展 type,type 也可以擴展 interface。

但需要注意的是,接口的擴展是繼承( extends )。類型別名的擴展就是交叉類型(通過 & 實現)

  1. // 接口 
  2. interface SisterAn { 
  3.     name: string; 
  4.  
  5. // 類型別名 
  6. type SisterRan = { 
  7.     age: number; 
  1. // 接口擴展接口 
  2. interface Sister extends SisterAn { 
  3.     age: number; 
  1. // 類型別名擴展類型別名 
  2. type SisterPro = SisterRan & { 
  3.     name: string; 
  1. // 接口擴展類型別名 
  2. interface Sister extends SisterRan { 
  3.     name: string; 
  1. // 類型別名擴展接口 
  2. type SisterPro = SisterAn & { 
  3.     age: number; 

區別

官方 中這樣介紹兩者的區別:

Type aliases and interfaces are very similar, and in many cases you can choose between them freely. Almost all features of an interface are available in type, the key distinction is that a type cannot be re-opened to add new properties vs an interface which is always extendable.

意思就是說幾乎接口的所有特性都可以通過類型別名來實現,主要區別在于:

1. 不同的聲明范圍

與接口不同,可以為任意的類型創建類型別名

類型別名的右邊可以是任何類型,包括基本類型、元祖、類型表達式( & 或 | 等);而在接口聲明中,右邊必須為變量結構。例如,下面的類型別名就不能轉換成接口

  1. type Name = string 
  2. type Text = string | { text: string }; 
  3. type Coordinates = [number, number]; 

2. 不同的擴展形式

接口是通過繼承的方式來擴展,類型別名是通過 & 來擴展

  1. // 接口擴展 
  2. interface SisterAn { 
  3.     name: string; 
  4. interface Sister extends SisterAn { 
  5.     age: number; 
  6.  
  7. // 類型別名擴展 
  8. type SisterRan = { 
  9.     age: number; 
  10. type SisterPro = SisterRan & { 
  11.     name: string; 

這里需要注意的是,接口擴展時,typescript 會檢查擴展的接口是否可以賦值給被擴展的接口

  1. // 接口擴展 
  2. interface SisterAn { 
  3.     name: string; 
  4.     age: string 
  5.  
  6. interface Sister extends SisterAn { 
  7.     name: string; 
  8.     age: number; 
  9. // 報錯: 
  10. //  Interface 'Sister' incorrectly extends interface 'SisterAn'
  11. //  Types of property 'age' are incompatible. 
  12. //  Type 'number' is not assignable to type 'string' 

但使用交集類型時就不會出現這種情況

  1. // 類型別名擴展 
  2. type SisterRan = { 
  3.  name: string; 
  4.     age: string; 
  5. type SisterPro = SisterRan & { 
  6.     name: string; 
  7.     age: number; 

類型別名擴展時,typescript 將盡其所能把擴展和被擴展的類型組合在一起,而不會拋出編譯時錯誤

3. 不同的重復定義表現形式

接口可以定義多次,多次的聲明會自動合并

  1. interface Sister { 
  2.     name: string; 
  3. interface Sister { 
  4.     age: number; 
  5.  
  6. const sisterAn: Sister = { 
  7.     name'sisterAn' 
  8. }  
  9. // 報錯:Property 'age' is missing in type '{ name: string; }' but required in type 'Sister' 
  10.  
  11. const sisterRan: Sister = { 
  12.     name'sisterRan',  
  13.     age: 12 
  14. // 正確 

但是類型別名如果定義多次,會報錯

  1. type Sister = { // Duplicate identifier 'Sister' 
  2.     name: string; 
  3.  
  4. type Sister = { // Duplicate identifier 'Sister' 
  5.     age: number; 

如何選擇 Interface 、 Type

雖然 官方 中說幾乎接口的所有特性都可以通過類型別名來實現,但建議優先選擇接口,接口滿足不了再使用類型別名,在 typescript 官網 Preferring Interfaces Over Intersections 有說明,具體內容如下:

大多數時候,對象類型的簡單類型別名的作用與接口非常相似

  1. interface Foo { prop: string } 
  2.  
  3. type Bar = { prop: string }; 

但是,一旦你需要組合兩個或多個類型來實現其他類型時,你就可以選擇使用接口擴展這些類型,或者使用類型別名將它們交叉在一個中(交叉類型),這就是差異開始的時候。

接口創建一個單一的平面對象類型來檢測屬性沖突,這通常很重要! 而交叉類型只是遞歸的進行屬性合并,在某種情況下可能產生 never 類型

接口也始終顯示得更好,而交叉類型做為其他交叉類型的一部分時,直觀上表現不出來,還是會認為是不同基本類型的組合。

接口之間的類型關系會被緩存,而交叉類型會被看成組合起來的一個整體。

最后一個值得注意的區別是,在檢查到目標類型之前會先檢查每一個組分。

出于這個原因,建議使用接口/擴展擴展類型而不是創建交叉類型。

  1. - type Foo = Bar & Baz & { 
  2. -     someProp: string; 
  3. - } 
  4. + interface Foo extends Bar, Baz { 
  5. +     someProp: string; 
  6. + } 

簡單的說,接口更加符合 JavaScript 對象的工作方式,簡單的說明下,當出現屬性沖突時:

  1. // 接口擴展 
  2. interface Sister { 
  3.     sex: number; 
  4.  
  5. interface SisterAn extends Sister { 
  6.     sex: string; 
  7. // index.ts(5,11): error TS2430: Interface 'SisterAn' incorrectly extends interface 'Sister'
  8. //  Types of property 'sex' are incompatible. 
  9. //    Type 'string' is not assignable to type 'number'
  1. // 交叉類型 
  2. type Sister1 = { 
  3.     sex: number; 
  4.  
  5. type Sister2 = { 
  6.     sex: string; 
  7.  
  8. type SisterAn = Sister1 & Sister2; 
  9. // 不報錯,此時的 SisterAn 是一個'number & string'類型,也就是 never 

來源:https://github.com/Advanced-Frontend/Daily-Interview-Question

 

責任編輯:武曉燕 來源: 三分鐘學前端
相關推薦

2022-09-02 09:02:44

TypeInterface

2022-05-06 09:21:21

TypeScriptinterfacetype

2021-11-11 07:02:33

類型函數調用

2021-11-30 23:01:51

編程語言數據Python

2019-08-28 15:38:04

Linux系統工具

2021-11-05 07:13:46

Python

2025-03-07 08:44:47

Typescriptiinterfacetype

2022-04-07 08:20:22

typeinterface前端

2021-06-23 08:01:18

TypeScript interface type

2020-01-17 13:33:42

大數據分析師大數據工程師

2018-06-16 14:32:16

無線路由器單頻雙頻

2010-03-29 17:38:18

CentOS源代碼

2021-03-15 14:09:49

電腦軟件安全

2020-09-23 09:08:05

typescript

2020-06-30 09:10:35

編程學習技術

2015-01-08 22:06:18

2009-09-15 09:24:42

思科認證考試思科認證

2022-03-13 23:31:13

JavaScript工具動畫庫

2020-09-23 16:53:46

Python編輯器工具
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 国产精品免费高清 | 久久久久久看片 | 在线免费观看欧美 | 国产综合av| 久久久国产一区二区三区四区小说 | 嫩草伊人| 日本不卡高清视频 | 精品网| 国产精品久久久久久久久久久久久 | 欧美午夜精品久久久久免费视 | 国产精品久久久久国产a级 欧美日韩国产免费 | 亚洲欧美一区二区三区国产精品 | 国产精品波多野结衣 | 久久精品国产99国产精品 | 久久久久久久久蜜桃 | 亚洲精品国产成人 | 久久99视频 | 久久久久久久久久久蜜桃 | 亚洲高清三级 | 羞羞的视频在线观看 | 欧美日韩国产一区二区三区 | 成人精品一区二区三区 | 日韩一区在线播放 | 亚洲 自拍 另类 欧美 丝袜 | 啪一啪在线视频 | 91视频久久久久 | 中文字幕视频在线 | 久久精品手机视频 | 国产精品久久久久久久7电影 | 91精品久久久 | 黄色大片在线 | 日韩欧美在线观看一区 | 成人免费视频网站 | 91欧美 | 国产毛片毛片 | 亚洲精品中文字幕在线观看 | 99精品免费 | 日韩高清三区 | 在线观看中文视频 | 伊人网在线综合 | 女女爱爱视频 |