文章目录

TypeScript 枚举类型在运行时的表现

发布于 2026-04-09 19:15:47 · 浏览 4 次 · 评论 0 条

TypeScript 枚举类型在运行时的表现

TypeScript 中的枚举虽然在开发阶段提供了类型安全,但在编译成 JavaScript 后,它们的行为并非完全一致。理解枚举在运行时的具体表现,有助于避免潜在的 bug 并优化打包体积。


1. 数字枚举与双向映射

数字枚举是 TypeScript 中最基础的枚举形式。当你在代码中定义一个数字枚举时,TypeScript 编译器会生成一个真正的 JavaScript 对象。这个对象不仅包含成员名到值的映射,还包含值到成员名的反向映射。

定义 一个名为 Status 的数字枚举:

enum Status {
  Pending,
  Success,
  Error
}

编译 上述代码,查看生成的 JavaScript 代码:

var Status;
(function (Status) {
  Status[Status["Pending"] = 0] = "Pending";
  Status[Status["Success"] = 1] = "Success";
  Status[Status["Error"] = 2] = "Error";
})(Status || (Status = {}));

观察 这段生成的代码,执行 Status[0] 会得到字符串 "Pending",而 Status["Pending"] 会得到数字 0

注意 这种双向映射会导致运行时代码体积增加,并且如果不小心遍历枚举对象,可能会同时遍历出键名和数字键。


2. 字符串枚举的单向映射

与数字枚举不同,字符串枚举在运行时不会生成反向映射。这意味着生成的 JavaScript 对象更轻量,且行为更符合常规对象的直觉。

定义 一个名为 Direction 的字符串枚举:

enum Direction {
  Up = "UP_VALUE",
  Down = "DOWN_VALUE"
}

编译 上述代码,查看生成的 JavaScript 代码:

var Direction;
(function (Direction) {
  Direction["Up"] = "UP_VALUE";
  Direction["Down"] = "DOWN_VALUE";
})(Direction || (Direction = {}));

尝试 访问 Direction["UP_VALUE"],结果会是 undefined

使用 字符串枚举可以有效地避免因为反向映射带来的混淆,适用于只需要通过键名获取值的场景。


3. 常量枚举的编译期内联

常量枚举使用 const enum 关键字定义。它们是 TypeScript 提供的一种优化手段,在编译阶段会被完全移除,所有使用到枚举值的地方都会被直接替换为具体的常量值。

定义 一个名为 ConstantStatus 的常量枚举:

const enum ConstantStatus {
  Ready,
  Set,
  Go
}

编写 调用代码:

const currentStatus = ConstantStatus.Ready;

编译 后查看生成的 JavaScript 代码:

var currentStatus = 0 /* ConstantStatus.Ready */;

观察 运行时环境中并不存在 ConstantStatus 这个对象。如果你在运行时需要动态获取枚举的键名(例如 ConstantStatus[0]),这种方式会报错。

注意 使用常量枚举可以显著减少运行时的代码体积,但必须确保不需要在运行时动态访问枚举对象本身。


4. 外部枚举与声明合并

外部枚举使用 declare enum 定义,通常用于描述已经存在于其他地方的枚举类型(例如在 .d.ts 声明文件中)。编译器默认不会为它们生成任何代码。

定义 一个外部枚举:

declare enum AmbientEnum {
  A = 1,
  B = 2
}

使用 该枚举:

const val = AmbientEnum.A;

编译 后的代码中,AmbientEnum.A 不会被替换为 1,而是保留原样 AmbientEnum.A。这意味着你必须确保在运行时,全局作用域或引入的库中已经定义了 AmbientEnum 变量,否则代码会在运行时报错。


5. 枚举类型对比总结

为了更直观地理解不同枚举在运行时的差异,请参考下表。

枚举类型 关键字 运行时产物 反向映射 适用场景
数字枚举 enum 真实 JavaScript 对象 (IIFE) 需要通过值获取键名,或用于位运算
字符串枚举 enum 真实 JavaScript 对象 (IIFE) 需要明确的字符串值,关注代码可读性
常量枚举 const enum 无 (代码内联) 追求极致性能,不需要运行时对象
外部枚举 declare enum 无 (保留引用) 取决于外部实现 声明第三方库或全局环境的类型

评论 (0)

暂无评论,快来抢沙发吧!

扫一扫,手机查看

扫描上方二维码,在手机上查看本文