5月的小火车要开走了🚎,【ts】——枚举类型

0 阅读3分钟

🚎 ᐝ⸝⸝夏一站: 六月,希望六月,大家一切顺利吧!

枚举类型的好处

  1. 提高可读性:用有意义的名字代替数字/字符串
// 没有枚举
if (status === 1) { /* 处理中 */ }
// 使用枚举,这里不懂得可以看一下下面的枚举的自动数字分配规则
enum OrderStatus {
 Pending,   // 待处理
 Processing,// 处理中
 Completed  // 已完成
}
if (status === OrderStatus.Processing) { /* 清晰! */ }
  1. 防止拼写错误:编译器会检查枚举值
// 容易出错
setStatus("procesing"); // 拼写错误也不会报错
// 使用枚举
setStatus(OrderStatus.Procesing); // 编译器会报错:拼写错误
  1. 集中管理常量:所有相关值在一个地方定义
// 修改时只需改一处
enum Theme {
  Light = "light-mode",
  Dark = "dark-mode"
}

枚举类型的使用

基础用法

// 数字枚举(默认从0开始)
enum Direction {
  Up,    // 0
  Down,  // 1
  Left,  // 2
  Right  // 3
}
// 字符串枚举
enum LogLevel {
  Info = "INFO",
  Warn = "WARNING",
  Error = "ERROR"
}
// 使用
const move = Direction.Up;
console.log(move); // 输出: 0
const error = LogLevel.Error;
console.log(error); // 输出: "ERROR"

高级用法

// 自定义起始值
enum StatusCodes {
  OK = 200,
  BadRequest = 400,
  Unauthorized = 401,
  NotFound = 404
}
// 混合枚举(不推荐,容易混乱)
enum Weird {
  A = 1,
  B = "two",
  C = 3
}
// 常量枚举(编译后会被删除,更高效)
const enum FastEnum {
  Fast,
  Faster,
  Fastest
}
const speed = FastEnum.Faster; // 编译后直接变成 const speed = 1;

枚举类型的底层逻辑

数字类型枚举

特点

  • 双向映射:可以通过名称获取值,也可以通过值获取名称
  • Color.Red === 0
  • Color[0] === "Red"
// TypeScript 代码
enum Color {
  Red,
  Green,
  Blue
}
// 编译后的js
var Color;
(function (Color) {
    Color[Color["Red"] = 0] = "Red";
    Color[Color["Green"] = 1] = "Green";
    Color[Color["Blue"] = 2] = "Blue";
})(Color || (Color = {}));
// 创建的对象结构
Color = {
  0: "Red",    // 值 → 名称
  1: "Green",
  2: "Blue",
  Red: 0,      // 名称 → 值
  Green: 1,
  Blue: 2
}

字符串类型枚举

特点

  • 单向映射:只能通过名称获取值
  • LogLevel.Info === "INFO"
  • LogLevel["INFO"] → undefined(无法通过值获取名称)
// TypeScript 代码
enum LogLevel {
  Info = "INFO",
  Warn = "WARNING",
  Error = "ERROR"
}
// 编译后的js
var LogLevel;
(function (LogLevel) {
    LogLevel["Info"] = "INFO";
    LogLevel["Warn"] = "WARNING";
    LogLevel["Error"] = "ERROR";
})(LogLevel || (LogLevel = {}));
创建的对象结构
LogLevel = {
  Info: "INFO",      // 名称 → 值
  Warn: "WARNING",
  Error: "ERROR"
}

为什么有这样的区别?

  1. 数字是可逆的

    • 数字是简单的整数,可以安全地作为对象键
    • 可以轻松实现双向查找(值→名称 和 名称→值)
  2. 字符串可能冲突

    • 字符串值可能包含特殊字符(如空格、标点)
    • 不同枚举成员可能有相同的字符串值
    • 强制双向映射可能导致意外覆盖

枚举的自动数字分配规则

  1. 默认从 0 开始:第一个成员如果没有初始化,默认为 0
  2. 后续成员自动递增:每个未初始化的成员会从前一个成员的值加 1
enum OrderStatus {
  Pending,   // 0 (自动分配)
  Processing,// 1 (自动分配)
  Completed  // 2 (自动分配)
}

建议写法

// 显式指定起始值(避免从0开始)
enum OrderStatus {
  Pending = 1,   // 明确设置为1
  Processing,    // 自动变成2
  Completed      // 自动变成3
}
// 这样使用时更清晰
if (status === OrderStatus.Processing) { // 2
  // 处理中
}

注意事项

enum Example {
  A,         // 0 (默认)
  B = 5,     // 手动设置为5
  C,         // 自动递增为6
  D = 10,    // 手动设置为10
  E          // 自动递增为11
}
console.log(Example.A); // 0
console.log(Example.B); // 5
console.log(Example.C); // 6
console.log(Example.D); // 10
console.log(Example.E); // 11

END!

枚举是 TypeScript 给开发者的礼物,合理使用能让代码更清晰安全! 🎁