typescript 中 enum 分普通和 const 两种:普通 enum 编译为运行时对象,支持正反向映射与遍历;const enum 编译时内联为字面量,无运行时开销但不支持反射。

TypeScript 中的 enum 是组织一组命名常量的有力方式,既提升可读性,又增强类型安全。它的使用不难,但编译行为差异——尤其是普通枚举与 const enum——直接影响运行时结构和性能,这点必须清楚。
怎么定义和使用 enum
枚举通过 enum 关键字声明,成员默认从 0 开始自动递增:
-
数字枚举:未显式赋值时按顺序编号,支持正向(名称 → 值)和反向(值 → 名称)映射。
例如:enum Status { Pending, Success, Failed }→Status.Pending === 0,Status[1] === "Success" -
手动初始化:可指定起始值或中间值,后续成员仍自动累加。
例如:enum Month { Jan = 1, Feb, Mar }→Month.Feb === 2 -
字符串枚举:每个成员必须显式赋字符串字面量,不支持反向映射(因为 JS 对象键不能是数字以外的非字符串类型)。
例如:enum Theme { Light = "light", Dark = "dark" }→Theme.Light返回"light",但Theme["light"]是undefined
普通 enum 编译后生成运行时对象
普通枚举会被完整编译为一个 JavaScript 对象,在运行时真实存在:
- 编译前:
enum Color { Red, Green, Blue } - 编译后 JS:
var Color = { Red: 0, Green: 1, Blue: 2 }; Color[0] = "Red"; Color[1] = "Green"; ... - 这意味着你可以在运行时访问
Color这个变量、遍历它、做in判断,甚至序列化进 JSON(注意:JSON.stringify 会丢掉反向映射部分)
const enum 编译时被完全内联,无运行时对象
加上 const 修饰后,枚举不会生成任何 JS 对象,所有引用点直接替换成字面量值:
- 编译前:
const enum Priority { Low, Medium, High }let p = Priority.Medium; - 编译后 JS:
var p = 1 /* Medium */;—— 没有Priority变量,也没有任何对象创建 - 优势:零运行时开销、更小包体积;限制:不能动态计算(如
const enum E { A = Math.random() }报错),也不能在需要反射或运行时枚举的场景中使用
什么时候选哪种?
- 需要运行时查值、遍历、调试、或与其他 JS 库交互 → 用普通 enum
- 纯前端状态码、HTTP 状态、固定配置项等只用于类型校验和字面量替换 → 优先用 const enum
- 不确定是否需要运行时能力?先用普通 enum;确认无此需求后再改 const,避免后期重构成本











