iT邦幫忙

2025 iThome 鐵人賽

DAY 9
0

今天我們要聊 TypeScript 裡常見的一個靈魂拷問:

物件型別要用 type 還是 interface?

初學者常覺得它們差不多,但其實有些關鍵差異,知道了之後你就能根據需求正確選擇。


1. 兩者的基本功能

Type Alias(型別別名)

用來為任何型別取一個名字,不只物件型別。

type User = {
  name: string;
  age: number;
};

它還能定義:

  • 基本型別別名
  • 聯合型別(|
  • 交叉型別(&
  • Tuple、函式型別
type ID = string | number;
type Point = [number, number];
type Add = (a: number, b: number) => number;

Interface(介面)

專門用來描述物件型別(以及 class 的結構)。

interface User {
  name: string;
  age: number;
}

它不能直接用來定義聯合型別、Tuple 等「非物件型別」。


2. 主要差異

功能/特性 Type Alias Interface
可描述物件型別
可描述聯合型別
可描述 Tuple
擴展型別(extends / implements) ❌(用交叉型別代替) ✅(extends)
可被多次宣告合併 ✅(Declaration Merging)
適用場景 靈活、可定義任何型別 主要用於物件、Class 契約

3. 擴展(Extend)差異

Type 用交叉型別擴展

type Person = { name: string };
type WithAge = Person & { age: number };

let p: WithAge = { name: "Alice", age: 25 };

Interface 用 extends

interface Person {
  name: string;
}
interface WithAge extends Person {
  age: number;
}

let p: WithAge = { name: "Bob", age: 30 };

4. Declaration Merging(宣告合併)

Interface 有個很酷的功能:可以多次定義同名介面,會自動合併。

interface User {
  name: string;
}
interface User {
  age: number;
}

let u: User = { name: "Charlie", age: 20 };

Type 就不行

type User = { name: string };
type User = { age: number }; // ❌ Duplicate identifier 'User'

5. 實務應用場景建議

  • 用 Type
    • 要定義聯合型別、交叉型別、Tuple
    • 型別需要靈活擴展、組合
    • 比較偏「資料結構」而非「物件契約」
  • 用 Interface
    • 定義物件型別,尤其是 Class 的結構
    • 需要宣告合併(例如第三方套件型別擴充)
    • 想讓型別設計跟 OOP 思維貼合

6. 實務案例

API 型別建議用 Type

type ApiResponse<T> = {
  data: T;
  status: number;
  message: string;
};

Class 契約建議用 Interface

interface Logger {
  log(message: string): void;
}

class ConsoleLogger implements Logger {
  log(message: string) {
    console.log(message);
  }
}

7. 常見誤解

  • 「用 Type 性能比較好」 → 在 TS 編譯階段沒有性能差異,選擇依需求。
  • 「Interface 一定比較適合物件」 → 大部分物件結構的確 OK,但有複雜型別組合時 Type 更方便。

上一篇
Day 8|型別也能混搭?Union & Intersection 全攻
下一篇
Day 10|函式型別:參數、回傳值全都要規範起來
系列文
我與型別的 30 天約定:TypeScript 入坑實錄12
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言