type
和 interface
的區別與優缺點
interface
的優缺點
優點:
可以擴展和合併
可以通過
extends
來繼承其他介面支援多次宣告同一個
interface
, 並自動合併屬性 (宣告合併)
interface Person {
name: string;
}
interface Person {
age: number;
}
const person: Person = { name: "David", age: 30 }; // 宣告合併
語義清晰
- 更接近物件導向中的
class
, 能清晰表達一個物件的結構
- 更接近物件導向中的
被推薦使用
- 官方建議使用 interface 來定義物件的結構, 特別是在定義 API 模型時
缺點:
不能直接定義聯合型別
- 不支持直接定義聯合型別 (Union Types), 但可以通過 擴展 和 交集 型別等來間接達成
type
的優缺點
優點:
更靈活
- 可以用來定義聯合型別、交集型別、元組 (Tuple) 等, 比
interface
更靈活
- 可以用來定義聯合型別、交集型別、元組 (Tuple) 等, 比
type Status = "success" | "error" | "loading"; // 聯合型別
type Person = { name: string } & { age: number }; // 交集型別
可以定義非物件型別
- type 可以定義原始類型 (如
string
、number
)、聯合型別等
- type 可以定義原始類型 (如
缺點:
無法合併型別
type
無法像interface
一樣進行宣告合併
可讀性較差
- 當處理複雜的型別結構時,
type
的靈活性可能會導致可讀性變差
- 當處理複雜的型別結構時,
何時使用 type or interface?
使用
interface
- 需要定義物件的 結構, 並且可能會在 多處擴展這個型別 的時候
使用
type
需要 定義 聯合型別、交集型別或其他複雜的型別操作的時候
需要 統整多種類型 的資料的時候,
type
提供了更好的靈活性
使用 type 和 interface 統整型別
使用 interface
進行交集型別:
export interface Human {
alive: boolean;
}
export interface User {
age: number;
}
export interface User {
name: "Jess" | "Lucy";
}
// User 會被自動合併,最終結構是 { age: number; name: "Jess" | "Lucy" }
// Human & User 來表示同時具有 Human 和 User 屬性的物件
const user1: Human & User = {
age: 23,
name: "Jess",
alive: true,
};
使用 type 進行聯合型別:
// type UserInfo 是 MaleUser 和 FemaleUser 的聯合型別,因此可以表示 MaleUser 或 FemaleUser 中的任何一種
type UserInfo = MaleUser | FemaleUser;
export type MaleUser = {
age: number;
name: "Jess" | "David";
};
export interface FemaleUser {
age: number;
pregnant: boolean;
}
export interface FemaleUser {
name: "Lucy";
}
const user: UserInfo = { age: 18, pregnant: false, name: "Lucy" };
if ("pregnant" in user) {
console.log(user.pregnant); // user 的型別是 FemaleUser
}
總結
type
用於定義複雜的型別操作, 支持聯合型別、交集型別等interface
則適合用來定義物件的結構, 且具有合併和擴展的特性
根據需求選擇 interface
或 type
也可以據情況結合使用