枚举用于定义一组命名的常量,使代码更具可读性和可维护性。
默认情况下,枚举值从 0 开始递增:
enum Direction {
Up,
Down,
Left,
Right
}
console.log(Direction.Up) // 0
console.log(Direction.Down) // 1
console.log(Direction.Left) // 2
console.log(Direction.Right) // 3
enum Direction {
Up = 1,
Down,
Left,
Right
}
console.log(Direction.Up) // 1
console.log(Direction.Down) // 2
enum Direction {
Up = 1,
Down = 3,
Left = 5,
Right = 7
}
enum Direction {
Up = "UP",
Down = "DOWN",
Left = "LEFT",
Right = "RIGHT"
}
console.log(Direction.Up) // "UP"
数字枚举支持反向映射:
enum Direction {
Up,
Down
}
console.log(Direction[0]) // "Up"
console.log(Direction["Up"]) // 0
字符串枚举不支持反向映射。
使用 const 定义的枚举会在编译时内联:
const enum Direction {
Up,
Down,
Left,
Right
}
let dir = Direction.Up
// 编译后
// let dir = 0
常量枚举性能更好,但不能反向映射。
混合数字和字符串(不推荐):
enum BooleanLikeHeterogeneousEnum {
No = 0,
Yes = "YES"
}
enum FileAccess {
None,
Read = 1 << 1,
Write = 1 << 2,
ReadWrite = Read | Write
}
console.log(FileAccess.Read) // 2
console.log(FileAccess.Write) // 4
console.log(FileAccess.ReadWrite) // 6
enum OrderStatus {
Pending = "PENDING",
Paid = "PAID",
Shipped = "SHIPPED",
Delivered = "DELIVERED",
Cancelled = "CANCELLED"
}
interface Order {
id: number
status: OrderStatus
}
function canCancel(order: Order): boolean {
return order.status === OrderStatus.Pending
}
const order: Order = {
id: 1,
status: OrderStatus.Pending
}
console.log(canCancel(order)) // true
enum Role {
Guest = 0,
User = 1,
Admin = 2,
SuperAdmin = 3
}
function hasPermission(role: Role, required: Role): boolean {
return role >= required
}
console.log(hasPermission(Role.Admin, Role.User)) // true
console.log(hasPermission(Role.User, Role.Admin)) // false
enum Color {
Red = "#FF0000",
Green = "#00FF00",
Blue = "#0000FF",
Yellow = "#FFFF00"
}
function getContrastColor(color: Color): Color {
switch (color) {
case Color.Red:
return Color.Blue
case Color.Blue:
return Color.Yellow
default:
return Color.Red
}
}
enum Weekday {
Monday = 1,
Tuesday,
Wednesday,
Thursday,
Friday,
Saturday,
Sunday
}
function isWeekend(day: Weekday): boolean {
return day === Weekday.Saturday || day === Weekday.Sunday
}
console.log(isWeekend(Weekday.Saturday)) // true
enum Color {
Red,
Green,
Blue
}
function getEnumValues<T>(enumObj: T): T[keyof T][] {
return Object.keys(enumObj)
.filter(key => typeof enumObj[key as keyof T] === 'number')
.map(key => enumObj[key as keyof T])
}
console.log(getEnumValues(Color)) // [0, 1, 2]
enum Status {
Active = "ACTIVE",
Inactive = "INACTIVE"
}
const statusLabels: Record<Status, string> = {
[Status.Active]: "激活",
[Status.Inactive]: "未激活"
}
console.log(statusLabels[Status.Active]) // "激活"
// 枚举
enum Direction {
Up,
Down
}
// 联合类型
type DirectionType = "Up" | "Down"
联合类型更轻量,枚举功能更丰富。
// 不推荐:简单场景用字面量
enum YesNo {
Yes = "YES",
No = "NO"
}
// 推荐:直接使用字面量
type YesNo = "yes" | "no"
enum Direction {
Up,
Down
}
// 编译后生成
var Direction
(function (Direction) {
Direction[Direction["Up"] = 0] = "Up"
Direction[Direction["Down"] = 1] = "Down"
})(Direction || (Direction = {}))
常量枚举不会生成额外代码。