TypeScript 聯合與交集型別 (Union and Intersection Types)
想像你在咖啡廳點餐:
- 「我要咖啡或茶」 -> 這就是聯合型別 (Union),二選一。
- 「我要一杯又冰又甜的飲料」 -> 這就是交集型別 (Intersection),兩個條件都要滿足。
1. 聯合型別 (Union Types) - 「或」 (OR)
使用 | 符號。這是 TypeScript 最強大的功能之一,它允許一個變數擁有多種身分。
// 變數可以是字串,也可以是數字
let id: string | number;
id = 'A123'; // OK
id = 101; // OK
// id = true; // 錯誤
為什麼需要它?
在 JavaScript 中,一個函式常常可以接受不同類型的參數。
function printId(id: string | number) {
// 這裡我們只知道 id 是 string 或 number
// 所以只能用它們「共有」的方法 (如 .toString())
console.log('Your ID is: ' + id.toString());
// 如果要用特有方法,必須先「收窄 (Narrowing)」
if (typeof id === 'string') {
// 這裡 id 被收窄為 string,可以用 toUpperCase
console.log(id.toUpperCase());
} else {
// 這裡 id 被收窄為 number
console.log(id.toFixed(2));
}
}
2. 交集型別 (Intersection Types) - 「且」 (AND)
使用 & 符號。它把多個型別「合併」成一個新的型別,這個新型別必須同時擁有所有型別的特徵。
這常混淆很多人,因為 & 看起來像是集合論的「交集」,但對物件來說,它比較像是「聯集」(把屬性加在一起)。
interface Draggable {
drag: () => void;
}
interface Resizable {
resize: () => void;
}
// UIComponent 必須「同時」具備 Draggable 和 Resizable 的能力
type UIComponent = Draggable & Resizable;
const box: UIComponent = {
drag: () => {},
resize: () => {},
};
陷阱:不可能的交集
如果你試圖把互斥的型別交集在一起,會得到 never (不可能存在的型別)。
// 世界上沒有一個值既是 string 又是 number
type Impossible = string & number; // 結果是 never
總結
| 符號 | 名稱 | 意義 | 記憶口訣 |
|---|---|---|---|
| | Union (聯合) | A 或 B | 選一個 (像是菜單點餐) |
& | Intersection (交集) | A 且 B | 全都要 (像是全能超人) |