Skip to content

建立 2026-09-15 更新 2026-09-15

Interface 與 Type

真實專案裡的資料幾乎都是物件:API 回傳的 JSON、元件的 props、表單資料。interfacetype 都是用來描述「這個物件長什麼樣子」的工具。

interface:描述物件形狀

interface User {
  id: number
  name: string
  email?: string   // 可選屬性
  readonly createdAt: Date // 建立後不能再被賦值
}

function printUser(user: User) {
  console.log(`${user.id}: ${user.name}`)
}

printUser({ id: 1, name: "Alice", createdAt: new Date() })

不需要 class 就能拿 interface 檢查一個一般物件字面值(object literal)符不符合形狀,這是 TypeScript 最日常的用法之一。? 是可選屬性,readonly 表示指定初值後不能再改。

type:型別別名

type Point = { x: number; y: number }

type ID = string | number   // type 可以描述聯合型別,interface 不行

const origin: Point = { x: 0, y: 0 }

type 能做 interface 做不到的事:幫 union、tuple、函式型別、甚至基本型別取一個別名。上面 基本型別 提到的 Status 字面值聯合型別,就只能用 type 寫。

interface 還是 type?

兩者能力有很大一部分重疊,描述一般物件形狀時大多可以互換:

情境 建議
描述物件/class 的公開介面 interface——之後要擴充時可以用 interface Foo { ... } 重複宣告來合併欄位
需要 union、tuple、函式型別、對基本型別取別名 只能用 type
沒有特別偏好 選一種在專案裡保持一致就好,不必兩種混著用

官方 Handbook 的建議是:能用 interface 就先用 interface,遇到 interface 做不到的情況(例如 union)再用 type

巢狀物件與陣列

interface Order {
  id: number
  items: { name: string; price: number }[]
  customer: User // 直接複用前面定義的 interface
}

型別可以互相組合:物件裡的屬性可以是另一個 interface,也可以是物件陣列。這種組合方式最後會建立到 類別泛型

相關影音

Traversy Media 這支涵蓋 interface 與型別別名的實際用法,可搭配本頁範例一起看。