enum是 TypeScript 提供的一个重要特性,它允许我们为一组数字或字符串定义一个更具描述性的名字。这使得代码更易读、更易于维护。
1.数字枚举
这是最常见的类型。默认情况下,枚举成员会被赋值为从 0 开始递增的数字。
enum Direction {
Up,
Down,
Left,
Right
}
let playerDirection = Direction.Up;
// console.log(playerDirection); // 0
// console.log(Direction.Right);// 3
//也可以手动为成员赋值,后面的值会自动递增
enum StatusCode {
NotFound = 404,
OK = 200,
ServerError = 500,
Created
}
// console.log(StatusCode.Created);// 501
2.字符串枚举
字符串枚举的成员必须都赋有字符串值。它的好处是,在调试时,打印出的值更具可读性。
enum DirectionString {
Up = "UP",
Down = "DOWN",
Left = "LEFT",
Right = "RIGHT"
}
// console.log(DirectionString.Up); // "UP"
3.异构枚举
枚举可以包含不同类型的成员。不推荐使用,可能会导致代码难以理解。
enum Status {
OK = 'OK',
Error = 1,
}
4.const枚举
如果你关心性能,并且确定枚举在编译后不需要作为一个对象存在,可以使用
const enum。
const enum Color { Red, Green, Blue }
特点:
- 编译时内联:在编译后,所有对
const enum成员的引用都会被替换为其具体的值。例如,Color.Red会直接被替换为0。 - 无运行时对象:编译后的 JavaScript 代码中不会存在
Color这个对象,这可以减少代码体积。 - 无反向映射:由于编译后对象不存在,自然也不支持反向映射。
5.数字,字符串,常量枚举之间的对比
| 特性 | 数字枚举 | 字符串枚举 | 常量枚举 |
|---|---|---|---|
| 成员值 | 数字 | 字符串 | 数组或字符串 |
| 反向映射 | ✔支持 | ❌不支持 | ❌不支持 |
| 运行时对象 | ✔生成 | ✔生成 | ❌不生成 |
| 可读性 | 一般 | 非常好 | 好 |
| 性能 | 一般 | 一般 | 非常好 |
| 场景 | 与旧有代码或外部系统(需要数字)交互 | 需要高可读性和明确性的场景(如日志、状态码) | 性能敏感、不需要运行时访问枚举对象的场景 |
6.反向映射
反向映射是
数字枚举的独特之处,它允许我们 通过枚举的值(value)来反向获取其对应的成员名(key) 。
enum Direction {
Up, // 0
Down, // 1
Left, // 2
Right // 3
}
// 反向映射:从值到成员名
const upKey = Direction[0]; // upKey 的值是 "Up"
const downKey = Direction[1]; // downKey 的值是 "Down"
const leftKey = Direction[2]; // leftKey 的值是 "Left"
const rightKey = Direction[3]; // rightKey 的值是 "Right"
console.log(upKey); // 输出: "Up"
console.log(downKey); // 输出: "Down"
反向映射是数字枚举在编译时通过生成一个双向引用的 JavaScript 对象来实现的。字符串枚举和常量枚举由于其设计目标和编译产物的不同,不具备此特性。
6.使用场景
栗子1:定义状态码或错误码
这是枚举最经典的应用场景。当你的应用程序有固定的几种状态或错误类型时,使用枚举可以增强类型安全和代码可读性,避免使用硬编码。
enum PaymentStatus {
Pending,
Success,
Failed,
Refunded,
}
const handlePayment = (status: PaymentStatus) => {
if (status === PaymentStatus.Success) {
console.log('Payment successful');
}
}
handlePayment(PaymentStatus.Success)//输出 Payment successful
栗子2:表示固定的选项集
当你有固定的选项列表,比如用户角色、权限级别或者 UI 主题时,枚举是一个很好的选择。
enum UserRole {
Admin = "ADMIN",
Editor = "EDITOR",
Guest = "GUEST"
}
const checkPermission = (role: UserRole)=> {
if (role === UserRole.Admin) {
// ... 执行管理员操作
}
}
栗子3:作为函数参数使用
在函数签名中使用枚举类型,可以明确地告诉调用者该参数应该传入什么类型的值,从而防止传入无效的 "魔术数字" 或字符串。
enum SortOrder {
Asc,
Desc,
}
const sortItems = (items: string[], order: SortOrder) => {
if (order === SortOrder.Asc) {
//升序
} else {
//降序
}
}
栗子4:在
switch语句中使用枚举与
switch语句是天作之合,可以让代码分支清晰明了。
enum OrderStatus {
Pending,
Processing,
Shipped,
Delivered,
Cancelled
}
const getOrderStatusMessage = (status: OrderStatus): string => {
switch (status) {
case OrderStatus.Pending:
return "订单待处理";
case OrderStatus.Processing:
return "订单处理中";
case OrderStatus.Shipped:
return "订单已发货";
case OrderStatus.Delivered:
return "订单已送达";
case OrderStatus.Cancelled:
return "订单已取消";
default:
// 通过 exhaustive check 确保所有情况都被处理
const _exhaustiveCheck: never = status;
return _exhaustiveCheck;
}
}
参考文章
小满zs 学习TypeScript10(枚举类型)xiaoman.blog.csdn.net/article/det…