第 9 章:枚举
学习目标
- 学会数字枚举和字符串枚举
- 理解常量枚举和外部枚举
- 掌握枚举与字面量类型的取舍
- 避开枚举的运行时代价
一、数字枚举
typescript
enum Direction {
Up, // 0(默认从 0 开始)
Down, // 1
Left, // 2
Right, // 3
}
const d: Direction = Direction.Up; // 0
console.log(Direction[0]); // 'Up'(反向映射)自定义起始值:
typescript
enum Status {
Success = 1,
Error = 2,
Loading = 5,
}
Status.Success; // 1
Status.Loading; // 5⚠️ 坑 1:数字枚举有反向映射(
Direction[0] === 'Up'),会生成额外的对象,影响运行时体积和性能。
二、字符串枚举(推荐)
typescript
enum LogLevel {
Info = 'INFO',
Warn = 'WARN',
Error = 'ERROR',
}
function log(level: LogLevel, msg: string): void {
console.log(`[${level}] ${msg}`);
}
log(LogLevel.Info, '启动成功'); // [INFO] 启动成功优势:
- 调试时可读
- 没有反向映射,运行时代价小
- 序列化成 JSON 友好
⚠️ 坑 2:字符串枚举不能反向映射,
LogLevel['INFO']不存在。
三、常量枚举(const enum)
typescript
const enum Color {
Red = '#FF0000',
Green = '#00FF00',
Blue = '#0000FF',
}
const c: Color = Color.Red;
console.log(c); // '#FF0000'(编译时直接内联,无对象)编译产物:
javascript
const c = '#FF0000'; // 没有 Color 对象生成⚠️ 坑 3:
const enum在 isolatedModules 模式下不能用(tsconfig.json开启"isolatedModules": true后,import type会编译失败)。Vite/ESBuild 用户推荐改用字面量联合。
四、外部枚举(declare enum)
声明一个已存在的枚举(常用于类型扩展):
typescript
declare enum ExternalLib {
A = 1,
B,
C,
}
const x: ExternalLib = ExternalLib.A;五、枚举与字面量联合的取舍
typescript
// 用字面量联合替代枚举(轻量、推荐)
type Status = 'success' | 'error' | 'loading';
function setStatus(s: Status): void {
console.log(s);
}
setStatus('success'); // ✅ 不用 Status.Success| 维度 | 枚举 | 字面量联合 |
|---|---|---|
| 运行时 | 生成对象(数字/字符串 enum) | 无 |
| 类型安全 | ✅ | ✅ |
| IDE 提示 | ✅ | ✅ |
| 反向映射 | 数字有,字符串无 | 无 |
| 体积 | 较大 | 几乎无 |
推荐:能用字面量联合就用字面量联合,枚举适合需要反向映射或大量成员的场景。
六、异构枚举(不推荐)
typescript
enum Mixed {
Yes = 'YES',
No = 0,
}混用数字和字符串,代码难读,禁止使用。
七、实战:API 状态码
typescript
enum HttpStatus {
OK = 200,
NotFound = 404,
ServerError = 500,
}
function handle(status: HttpStatus): string {
switch (status) {
case HttpStatus.OK: return '成功';
case HttpStatus.NotFound: return '没找到';
case HttpStatus.ServerError: return '服务器错误';
}
}八、本章小结
| 要点 | 关键 |
|---|---|
| 数字枚举 | 默认从 0 开始,有反向映射 |
| 字符串枚举 | 推荐,无反向映射,可读性好 |
| 常量枚举 | const enum,编译时内联,无对象 |
| declare enum | 声明外部已存在的枚举 |
| 推荐 | 字面量联合 'a' | 'b' 更轻量 |
| 异构 | 禁止混用数字和字符串 |
动手练习
- 字符串枚举:定义
Weekday = 'Mon' \| ... \| 'Sun'(用字面量) 或enum - HTTP 状态:用枚举定义 HTTP 状态码,写
isError(status)函数 - const enum:开启
isolatedModules看const enum是否报错
下一章:第 10 章:装饰器 →