核心結論
在大多數情況下,它們可以互換使用,都能描述對象的結構。它們的區別更多在于設計和擴展能力上。
主要區別總結表
特性 | interface (接口) | type (類型別名) |
---|---|---|
擴展方式 | 使用?extends ?繼承interface A extends B {} | 使用?& ?交叉類型type A = B & C |
合并聲明 | 支持:同名接口會自動合并 | 不支持:同名類型會報錯 |
描述能力 | 主要描述對象形狀 | 功能更強,可描述任意類型(聯合、元組、原始類型等) |
實現 (implements) | 可以被類實現class C implements A {} | 可以被類實現(描述對象時)class C implements A {} |
性能 | 輕微優勢:在錯誤信息和性能上,早期有細微差別,現在可忽略不計 | |
可讀性 | 更偏向于?OOP(面向對象編程)風格,表示一個“契約” | 更偏向于?FP(函數式編程)風格,像一個類型表達式 |
詳細解釋與示例
1. 擴展 (Extending)
interface?使用繼承,更符合傳統 OOP 思維。
interface Animal {name: string; }interface Bear extends Animal {honey: boolean; }
type?使用交叉類型 (&),更像是邏輯運算。
type Animal = {name: string; }type Bear = Animal & {honey: boolean; }
2. 聲明合并 (Declaration Merging)
這是兩者最關鍵的區別。
interface:支持合并。如果你定義了兩個同名的接口,TypeScript 會將它們合并為一個。
interface User {name: string; }interface User {age: number; }// 最終 User 接口為:{ name: string; age: number; } const user: User = { name: 'John', age: 30 }; // 正確
這個特性非常有用,尤其是在為第三方庫或全局對象(如?
Window
)添加自定義屬性時。type:不支持合并。重復聲明同名的類型別名會報錯。
type User = {name: string; }type User = { // Error: Duplicate identifier 'User'age: number; }
3. 描述能力 (Descriptive Capabilities)
interface:基本上只能用于定義對象的類型結構。
interface Point {x: number;y: number; }
type:功能更強大,可以定義任何類型。
// 聯合類型 (Union) type ID = string | number;// 元組類型 (Tuple) type PointTuple = [number, number];// 原始類型別名 type Name = string;// 從其他類型映射 (Mapped Types) type Nullable<T> = { [P in keyof T]: T[P] | null };
最佳實踐與如何選擇
雖然很多時候可以互換,但社區形成了一些共識:
優先使用?
interface
:當你需要定義對象的形狀并希望使用聲明合并時(例如,庫的類型定義、擴展全局對象)。
在面向對象風格的代碼中,定義類和它們之間的契約。
使用?
type
?的情況:當你需要定義聯合類型、元組或映射類型時。
當你需要重命名或定義復雜類型表達式時。
當你需要一個函數的類型時(通常用?
type
)。type ClickHandler = (event: MouseEvent) => void;
保持一致性:
在一個項目中,最好對同一種用途保持統一。例如,全部用?
interface
?定義對象,或者全部用?type
。混用會增加項目的認知負擔。
總結
場景 | 推薦 |
---|---|
定義對象形狀(尤其是需要被實現的) | interface ?(或?type ) |
需要聲明合并(如擴展庫類型) | 必須用?interface |
定義聯合類型、元組 | 必須用?type |
定義函數類型 | 通常用?type |
簡單重命名原始類型 | 通常用?type |
一句話總結:interface
?更適合定義對象契約和實現 OOP 的繼承,而?type
?更強大靈活,適合定義各種復雜的類型關系。?對于大多數應用開發,遵循?優先使用 interface 定義對象,在 interface 能力不足時使用 type
?是一個很好的策略。
一句話核心區別
interface 是官方合同范本,type 是萬能自定義模板
詳細對比(方便記憶)
1. 擴展方式不同
interface 用?
extends
(繼承)→ 像兒子繼承爸爸type 用?
&
(交叉)→ 像把兩張紙粘在一起
2. 重復定義時
interface → 會自動合并(像在合同上追加條款)
type → 會報錯(像不允許有兩個同名的模板)
3. 能定義的內容
interface → 主要定義對象形狀
type → 什么都能定義(對象、聯合類型、元組等)
4. 使用場景
需要被類實現時 → 優先用 interface
需要定義復雜類型時 → 只能用 type
記憶口訣
接口能合并,類型更萬能
對象用接口,復雜用類型
擴展用繼承,交叉類型連
類要實現時,接口是首選
簡單選擇指南
大部分情況下定義對象 → 用 interface
需要合并聲明時 → 必須用 interface
需要定義聯合類型、元組等 → 必須用 type
記住這個比喻:interface 是標準合同,type 是自定義模板,就能很好區分了