TypeScript编程03-枚举

TypeScript编程03-枚举

文章目录

一、枚举基础概念

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:

  1. 可读性强:运行时值是有意义的字符串
  2. 调试友好:打印出来直接看懂
  3. 序列化方便:与 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 参数、配置项 纯类型、性能敏感

相关推荐
冰暮流星2 小时前
javascript之dom查询操作2
开发语言·javascript·ecmascript
小陈工2 小时前
Python Web开发入门(九):权限管理与角色控制实战
服务器·开发语言·前端·数据库·python·安全·sqlite
DFT计算杂谈2 小时前
eDMFT安装教程
java·服务器·前端·python·算法
Gazer_S2 小时前
【GitLab npm Registry 非标准端口安装问题解决方案】
前端·npm·gitlab
Aliex_git2 小时前
前端监控笔记(二)
前端·笔记·学习
光影少年2 小时前
实现发布订阅模式
前端·javascript·设计模式
阿珊和她的猫2 小时前
TypeScript中const与readonly的区别与应用解析
javascript·typescript·状态模式
chushiyunen2 小时前
python web框架streamlit
开发语言·前端·python
迷糊小鬼2 小时前
Button matrix(矩阵按钮) (lv_buttonmatrix)
c语言·开发语言·前端·ui·矩阵