在前面章節中,大家應該會很疑惑 type 和 interface 在很多方面都可以實現相似的功能,那我們應該要使用哪一種呢?下面來看看兩者存在了哪些區別:
type 通常用於定義自定義的型別,它可以是基本型別、聯合類型、交叉類型,甚至是函數類型等
,使用 type 可以更靈活地組合和轉換型別。
type TPoint = { x: number; y: number };
type TStatus = "success" | "error" | "warning";
type TResult<T> = { data: T; status: TStatus };
interface 通常用於定義物件的結構和形狀以及屬性之間的型別。
interface IUser {
id: number;
name: string;
age: number;
address: string;
}
interface IAnimal {
name: string;
sound: string;
makeSound(): void;
}
interface IData<T> {
[key: string]: T;
}
如果需要定義物件結構,通常使用 interface
。
interface ICar {
model: string;
year: number;
startEngine(): string;
}
// 使用 implements 來實現類別,以符合接口的結構
class Ferrari implements ICar {
constructor(public model: string, public year: number) {
this.model = model;
this.year = year;
}
startEngine(): string {
return `這台 ${this.year} 年的 ${this.model},要按方向盤的紅色按鈕來啟動。`;
}
}
const ferrari = new Ferrari("LaFerrari", 2024);
console.log(ferrari.startEngine()); // 輸出: 這台 2024 年的 LaFerrari,要按方向盤的紅色按鈕來啟動。
如果需要 用 utility 轉換成新型別 (Partial、Pick、Omit),通常會使用 type
。
interface IOrder {
id: number;
product: string;
quantity: number;
};
type TPartialOrder = Partial<IOrder>;
如果是需要擴展其他型別或定義可選屬性,兩者皆可使用,可以依據個人喜好或專案來選擇。
type TOrder = {
id: number;
product?: string;
quantity?: number;
};
// 類型別名擴展
type TExtendsOrder = TOrder & {
description: string;
};
interface IOrder {
id: number;
product?: string;
quantity?: number;
};
// 接口擴展
interface IExtendsOrder extends IOrder {
description: string
}
type 和 interface 兩者也可以互相擴展成對方。不過除非必要,不然威爾豬自己是不會這樣做。
interface IAnimal {
name: string;
}
interface ISound {
sound: string;
}
type TDog = IAnimal & ISound;
const myDog: TDog = {
name: "旺財",
sound: "汪汪汪",
};
type TAnimal = {
name: string;
};
type TSound = {
sound: string;
};
interface IDog extends TAnimal, TSound {}
const myDog: IDog = {
name: "旺財",
sound: "汪汪汪",
};
我們來看 TypeScript 官網的兩段話:
所以由官網得知,type 和 interface 在大多數情況下可以實現相似的功能,對於要使用 type 還是 interface,大多數情況下可以根據個人喜好來選擇使用
,我們也可以依據程式碼設計和專案需求來進行選擇。下面是威爾豬的一些參考原則,分享給大家:
type | interface | |
---|---|---|
使用時機 | 定義聯合類型、交叉類型,或者需要自定義的型別 | 聲明物件的結構和形狀 |
擴展方式 | & | extends (擴展性較好) |
可選屬性 | 通常使用 Partial | 通常使用可選串連 (?) |
聲明合併 | ❌ | ⭕️ (同名稱即可) |
類別 (class) | ❌ | ⭕️ (implements) |
如果真的無法決定要使用哪一種,就問前輩或主管吧,讓 type 還是 interface 使用可以更加一致。