昨天我們聊了物件型別,今天來認識 TypeScript 裡的 Enum(列舉型別)。
它的使命很簡單:
幫一組相關的常數找一個統一管理的家。
當你的專案裡出現一大堆字串或數字常數,
就很容易打錯或忘記有哪些選項。
Enum(列舉)就是為了幫這些常數找個家。
想像你有一組訂單狀態:
let status = "Created"; // 其他地方用 "Paid"
let anotherStatus = "Shipped"; // 還有人打成 "Shiped"(typo)
問題:
解法:用 Enum 定義規範。
enum Direction {
Up,
Down,
Left,
Right
}
let move: Direction = Direction.Up;
預設會從 0 開始編號,Direction.Up = 0,Direction.Down = 1...
你可以手動指定 Enum 的值,常用於 API 或有業務意義的數值:
enum Role {
Admin = "ADMIN",
User = "USER",
Guest = "GUEST"
}
數字 Enum 在編譯後會同時支援「由值找鍵」:
enum Status {
Success = 200,
NotFound = 404
}
console.log(Status.Success); // 200
console.log(Status[200]); // "Success"
注意:字串 Enum 沒有這功能。
效能優化:編譯後會直接用值取代,不保留對象結構。
const enum HttpStatus {
OK = 200,
NotFound = 404
}
let code = HttpStatus.OK; // 編譯後直接變成 200
優點:少一層存取
缺點:不能做反向查詢
enum OrderStatus {
Created = "CREATED",
Paid = "PAID",
Shipped = "SHIPPED",
Cancelled = "CANCELLED"
}
function getOrderStatusText(status: OrderStatus) {
switch (status) {
case OrderStatus.Created:
return "訂單已建立";
case OrderStatus.Paid:
return "已付款";
case OrderStatus.Shipped:
return "已出貨";
case OrderStatus.Cancelled:
return "已取消";
}
}
enum Permission {
Read = 1 << 0,
Write = 1 << 1,
Execute = 1 << 2
}
let userPermission = Permission.Read | Permission.Write;
有時候你會發現,用字面量聯合型別也能做到類似效果:
type OrderStatusLiteral = "CREATED" | "PAID" | "SHIPPED" | "CANCELLED";
差異:
如果你需要在 程式執行時 取到 Enum 值,用 Enum。如果只是做型別檢查,用 Union 較輕量。
enum Test {
A = 1, // 1
B, // 2
C // 3
}