TypeScript编程03-枚举
文章目录
- TypeScript编程03-枚举
-
- 一、枚举基础概念
-
- Q1:什么是枚举(Enum)?
- [Q2:TypeScript 支持哪几种枚举类型?](#Q2:TypeScript 支持哪几种枚举类型?)
- 二、数字枚举详解
- 三、字符串枚举详解
- 四、枚举的使用技巧
- 五、常量枚举与计算成员
-
- [Q10:什么是 `const enum`(常量枚举)?](#Q10:什么是
const enum(常量枚举)?) - Q11:什么是计算成员?
- [Q10:什么是 `const enum`(常量枚举)?](#Q10:什么是
- 六、枚举与类型系统
- 七、枚举的局限与替代方案
- 八、常见问题速查
- 总结对比表
一、枚举基础概念
Q1:什么是枚举(Enum)?
A: 枚举是一种数据结构,用于定义一组命名的常量集合。TypeScript 提供了基于数字和字符串的枚举,让代码更具可读性和可维护性。
typescript
enum Direction {
Up,
Down,
Left,
Right
}
Q2:TypeScript 支持哪几种枚举类型?
A: 三种主要类型:
| 类型 | 说明 |
|---|---|
| 数字枚举 | 默认从 0 开始自增,可自定义初始值 |
| 字符串枚举 | 每个成员必须是字符串字面量 |
| 异构枚举 | 混合数字和字符串(不推荐) |
二、数字枚举详解
Q3:数字枚举的默认值是如何分配的?
A: 默认从 0 开始,依次自增 +1。
typescript
enum Status {
Pending, // 0
Approved, // 1
Rejected // 2
}
Q4:如何自定义数字枚举的起始值?
A: 给第一个成员赋值,后续成员自动递增。
typescript
enum HttpStatus {
OK = 200,
Created, // 201
BadRequest, // 400? 不对!是 201
NotFound = 404,
Error // 405
}
Q5:数字枚举支持反向映射吗?
A: 支持。可以通过值获取名称。
typescript
enum Color {
Red = 1,
Green,
Blue
}
console.log(Color.Red); // 1
console.log(Color[1]); // "Red" ← 反向映射
console.log(Color["Red"]); // 1
⚠️ 注意:字符串枚举不支持反向映射!
三、字符串枚举详解
Q6:如何定义字符串枚举?
A: 每个成员必须显式赋值为字符串。
typescript
enum Direction {
Up = "UP",
Down = "DOWN",
Left = "LEFT",
Right = "RIGHT"
}
Q7:字符串枚举的优势是什么?
A:
- 可读性强:运行时值是有意义的字符串
- 调试友好:打印出来直接看懂
- 序列化方便:与 JSON 兼容性好
typescript
// 对比
enum NumDir { Up, Down } // 运行时: Up = 0
enum StrDir { Up = "UP" } // 运行时: Up = "UP"
JSON.stringify(StrDir.Up) // "UP" ✅
JSON.stringify(NumDir.Up) // 0(可读性差)⚠️
四、枚举的使用技巧
Q8:如何获取枚举的所有键或值?
A:
typescript
enum Status {
Active = 1,
Inactive = 0
}
// 获取所有键(包括反向映射的键,仅数字枚举)
Object.keys(Status); // ["1", "0", "Active", "Inactive"]
// 过滤只获取字符串键
Object.keys(Status).filter(key => isNaN(Number(key))); // ["Active", "Inactive"]
// 获取所有值
Object.values(Status); // ["Active", "Inactive", 1, 0]
Q9:如何遍历枚举?
A:
typescript
enum Color {
Red = "RED",
Green = "GREEN"
}
// 字符串枚举遍历
for (const key in Color) {
console.log(`${key}: ${Color[key]}`);
}
// 输出: Red: RED, Green: GREEN
// 数字枚举遍历(注意会包含反向映射)
enum NumColor { Red = 1, Green }
for (const key in NumColor) {
if (isNaN(Number(key))) { // 过滤数字键
console.log(`${key}: ${NumColor[key]}`);
}
}
五、常量枚举与计算成员
Q10:什么是 const enum(常量枚举)?
A: 编译时完全内联,不生成对象,提升性能。
typescript
const enum Direction {
Up = 1,
Down = 2
}
let dir = Direction.Up;
// 编译后: let dir = 1 /* Up */; (直接替换为值)
⚠️ 限制 :不能包含计算成员,且编译后无法访问
Direction对象。
Q11:什么是计算成员?
A: 运行时才能确定的值。
typescript
enum FileAccess {
None = 0,
Read = 1 << 1, // 2 (位运算)
Write = 1 << 2, // 4
ReadWrite = Read | Write, // 6 (引用其他枚举成员)
G = "123".length // 3 (表达式)
}
六、枚举与类型系统
Q12:枚举作为类型如何使用?
A: 枚举本身是一种类型。
typescript
enum Status {
Success = 200,
Error = 500
}
function handle(status: Status) { // 参数类型为枚举
if (status === Status.Success) {
console.log("成功");
}
}
handle(Status.Success); // ✅
handle(200); // ✅ 数字枚举允许字面量
handle(404); // ❌ 错误:404 不是 Status 的成员
Q13:联合枚举类型是什么?
A: 枚举成员可以作为类型使用。
typescript
enum ShapeKind {
Circle = "circle",
Square = "square"
}
interface Circle {
kind: ShapeKind.Circle; // 只能是 "circle"
radius: number;
}
interface Square {
kind: ShapeKind.Square; // 只能是 "square"
sideLength: number;
}
七、枚举的局限与替代方案
Q14:枚举有哪些缺点?
A:
| 缺点 | 说明 |
|---|---|
| 代码体积 | 编译后生成双向映射对象,增加体积 |
| 类型安全 | 数字枚举允许任意数字赋值(status: Status = 999 不报错) |
| Tree Shaking | 普通枚举难以被优化掉 |
| 命名空间污染 | 枚举名和值都在作用域内 |
Q15:什么场景下应该用对象字面量替代枚举?
A: 推荐用 as const 对象替代简单枚举。
typescript
// ❌ 传统枚举
enum Colors {
Red = "RED",
Blue = "BLUE"
}
// ✅ 推荐:const 断言对象(更轻量,类型更安全)
const Colors = {
Red: "RED",
Blue: "BLUE"
} as const;
type Color = typeof Colors[keyof typeof Colors]; // "RED" | "BLUE"
优势:
- 无编译开销
- 更好的 Tree Shaking
- 真正的字面量类型推导
八、常见问题速查
Q16:枚举成员可以是哪些类型?
A:
- ✅ 数字字面量
- ✅ 字符串字面量
- ✅ 引用其他常量枚举成员
- ✅ 带括号的简单表达式
- ❌ 变量、函数调用等运行时值(除非用
const enum且表达式是编译期常量)
Q17:如何比较枚举值?
A:
typescript
enum Status { Ok = 1, Error = 2 }
const s: Status = 1;
// 三种等价写法
s === Status.Ok; // ✅ 推荐
s === 1; // ✅ 数字枚举允许
s as number === 1; // ✅ 显式转换
Q18:如何提取枚举的值类型?
A:
typescript
enum MyEnum {
A = "a",
B = "b"
}
// 获取所有值的联合类型
type MyEnumValue = `${MyEnum}`; // "a" | "b"
// 或
type MyEnumValue2 = typeof MyEnum[keyof typeof MyEnum]; // MyEnum.A | MyEnum.B
总结对比表
| 特性 | 数字枚举 | 字符串枚举 | const enum |
|---|---|---|---|
| 编译后体积 | 较大(双向映射) | 较大 | 无(内联) |
| 反向映射 | ✅ 支持 | ❌ 不支持 | ❌ 不支持 |
| 运行时访问 | ✅ 可以 | ✅ 可以 | ❌ 不可以 |
| 类型安全 | ⚠️ 较松 | ✅ 严格 | ✅ 严格 |
| 推荐场景 | 位运算、需要反向映射 | API 参数、配置项 | 纯类型、性能敏感 |