简单聊下enum(枚举)

当你需要定义一些固定值的集合的场景时,你通常都是如何考虑的?例如对于一个订单状态集合,未支付、支付成功、支付失败、已取消、已发货、已签收、已退款,对应的数字分别是:1、2、3、4、5、6、7。

type字面量联合类型

你会选择定义一个单纯的类型,简洁直观,无运行开销吗?

typescript 复制代码
type OrderStatus = 1 | 2 | 3 | 4 | 5 | 6 | 7

但这并非理想方案。它本质是类型约束,而非 "集合"------ 无法通过 "键"(如 "未支付")访问对应的值(1),必须手动写数字或字符串,即使 TypeScript 会校验,仍存在拼写或记错值的风险。

普通对象

最初我使用普通对象去满足这项要求:

typescript 复制代码
const OrderStatus = {
  UNPAID: 1,
  PAID_SUCCESS: 2,
  PAID_FAILED: 3,
  CANCELLED: 4,
  SHIPPED: 5,
  SIGNED: 6,
  REFUNDED: 7,
}

可以直接通过"键"访问值,例如OrderStatus.UNPAID,这是我想要的。 但是这种方式也有一些不直观的地方,类型松散,TS会自动推断该对象的类型为{ UNPAID: number, PAID_SUCCESS: number, PAID_FAILED: number, CANCELLED: number, SHIPPED: number, SIGNED: number, REFUNDED: number },这显然不是我想要的。

另外,虽然枚举类型规定了1-7,但是我直接赋值其他number类型数字,也是没啥问题的,TS也不会报错。

当然这个也有解决方式,就是使用as const断言,将对象的所有属性都变成只读的字面量类型。

typescript 复制代码
const OrderStatus = {
  UNPAID: 1,
  PAID_SUCCESS: 2,
  PAID_FAILED: 3,
  CANCELLED: 4,
  SHIPPED: 5,
  SIGNED: 6,
  REFUNDED: 7,
} as const

这样,TS就会自动推断该对象的类型为{ readonly UNPAID: 1, readonly PAID_SUCCESS: 2, readonly PAID_FAILED: 3, readonly CANCELLED: 4, readonly SHIPPED: 5, readonly SIGNED: 6, readonly REFUNDED: 7 },这显然是我想要的。

兼具了普通对象的"键"访问值的便利性,同时也具备了枚举类型的"值"访问键的便利性。 但是它又不能当作类型去使用,需要手动使用typeof OrderStatus来提取它的联合类型。

typescript 复制代码
type OrderStatusT = typeof OrderStatus[keyof typeof OrderStatus]

所以要兼具普通对象的"键"访问值的便利性,同时也具备了枚举类型的"值"访问键的便利性,以及使用联合类型。那么只能另辟蹊径了。

enum

最后可以选择使用枚举类型去满足:

typescript 复制代码
enum OrderStatus {
  UNPAID = 1,
  PAID_SUCCESS = 2,
  PAID_FAILED = 3,
  CANCELLED = 4,
  SHIPPED = 5,
  SIGNED = 6,
  REFUNDED = 7,
}

如图所示,优势不言而喻了。

相关推荐
用户0934077735142 小时前
HarmonyOS WPS Open SDK 实践:从 HAR 集成到 OpenFileRequest 最小闭环
typescript·harmonyos
FYKJ_20103 小时前
springboot雅集社区养老管理系统04456-计算机课程设计、毕业设计
vue.js·spring boot·python·mysql·typescript·spark·django
FYKJ_20103 小时前
express皖美特色农产品网售系统53118-计算机课程设计、毕业设计
javascript·vue.js·spring boot·mysql·typescript·spark·express
FYKJ_20103 小时前
springboot羽毛球场地管理系统00626-计算机课程设计、毕业设计
vue.js·spring boot·python·mysql·typescript·spark·django
FYKJ_20104 小时前
django药饮个性化推荐系统54839-计算机课程设计、毕业设计
vue.js·spring boot·python·mysql·typescript·spark·django
濮水大叔9 小时前
Cabloy全栈框架的两个SSR入口:Vona集成式SSR vs Zova独立式SSR
typescript·node.js·全栈
nyaomaru9 小时前
你的 Type Guard 可能会悄悄地与 TypeScript 类型发生偏移 🔧
后端·typescript
右耳朵猫AI8 天前
Web前端周刊2026W38 | React 19.3 发布、StyleX 深潜、jsdom 30.1 提速
前端·javascript·react.js·typescript·node.js
溪语流沙8 天前
Django + Vue电商项目第001讲:开篇|注册登录加增删改查,那不是电商
redis·python·mysql·docker·typescript·django·vue
掰头战士9 天前
多重影分身!恨不得把一个agent掰成两个? 还真能干!
typescript·llm·agent