TypeScript 枚举(Enums)详解

枚举消灭魔法值:字符串枚举、数字枚举、const 枚举的用法与取舍,以及"现代 TS 是否还需要 enum"的争议解析。

最佳实践
类型结构与组件组合插画

枚举把魔法值收拢为命名常量:enum Status { Active = 'ACTIVE', Inactive = 'INACTIVE' }——自文档化 + 编译期校验。现代替代:as const 对象 + 联合类型(与 JS 产物更亲和);enum 仍适合需要运行时对象的场景。

消灭魔法值

// 魔法值散落各处
if (status === 'ACTVIE') {}   // 拼错了编译器不管

// 枚举:单一事实源
enum Status {
  Active = 'ACTIVE',
  Inactive = 'INACTIVE',
  Pending = 'PENDING',
}

if (status === Status.Active) {}   // 拼错编译报错

字符串枚举优先——日志与调试中可读,数字枚举(默认 0/1/2 自增)的可读性与序列化友好度都差。

const 枚举与树摇

const enum Direction { Up, Down }
const d = Direction.Up;   // 编译后直接内联为 0——零运行时代码

const enum 产物内联——但与现代工具链(isolatedModules)冲突,多数现代项目指南建议避免。

现代替代:as const 方案

const Status = { Active: 'ACTIVE', Inactive: 'INACTIVE' } as const;
type Status = typeof Status[keyof typeof Status];
// 'ACTIVE' | 'INACTIVE'

与 enum 等价的类型安全,产物是普通 JS 对象——无运行时特殊性、tree-shaking 友好、与类型剥离工具链(tsx/esbuild)完全兼容。

选择建议

场景 选择
需要运行时枚举对象 + 经典模式 enum
现代工具链(tsx/原生 TS) as const 方案
配置驱动、序列化交互 as const 方案

常见问题(FAQ)

Q:enum 是"坏味道"吗?

不是——它是 TS 独有的运行时产物(与 JS 的语义差异),这在类型剥离时代成为摩擦点。as const 方案因此流行,但 enum 本身设计良好。

Q:数字枚举的反向映射?

数字枚举编译后有"值→名"的反向映射(Status[0] === 'Active')——少见但有用的特性,字符串枚举没有。

Q:switch 穷尽枚举?

配 never 检查(见本系列《never 与 公开资料未说明》)——枚举加成员时所有 switch 编译报错,防漏处理。


参考文档

本文依据公开文档整理,示例需按项目依赖版本验证;不将文档中的性能描述视为本项目实测结果。

延伸阅读

获取专属方案

联系我们

加入社区

微信扫码
加入官方交流群

立即体验

在线开通,按量计费,真正的云服务!

立即开始

选择观测云版本

代码托管平台