You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何获取TypeScript中const enum的大小?

如何计算TypeScript const enum的大小?

假设我们定义了这样的const enum:

const enum Fruit {
  Apple = 1,
  Banana,
  Carrot,
  Dragonfruit
}

它的实际成员数量是4,但和普通enum不同,const enum编译后会被完全内联,不会生成对应的对象,所以没法用Object.keys(Fruit).length这类方法计算大小。

有人会推荐给enum加一个__SIZE成员来标记大小:

const enum Fruit {
  Apple = 1,
  Banana,
  Carrot,
  Dragonfruit,
  __SIZE
}

然后通过Fruit.__SIZE获取值,但这个方案有两个明显问题:

  • 联网场景下新增枚举项时,新成员会占用原来__SIZE的数值位置,导致新成员ID和历史数据中的__SIZE/NULL插槽ID冲突,引发数据问题。
  • 必须始终保证__SIZE是最后一个成员,开发者容易遗忘同步,出错概率高。

下面是几个可行的替代方案,因为只需要在应用启动时计算一次,就算速度慢也没关系:

方案1:手动维护枚举值数组 + 类型校验

创建一个包含所有const enum成员的数组,直接取数组长度作为枚举大小。同时用TypeScript的类型约束强制数组覆盖所有成员,避免遗漏:

const enum Fruit {
  Apple = 1,
  Banana,
  Carrot,
  Dragonfruit
}

// 手动添加所有枚举值到数组
const fruitValues = [Fruit.Apple, Fruit.Banana, Fruit.Carrot, Fruit.Dragonfruit] as const;
// 直接取数组长度作为枚举大小
const FRUIT_SIZE = fruitValues.length; // 结果为4

// 可选:添加类型校验,确保数组包含所有枚举成员
type AllFruitMembers = Exclude<Fruit, typeof fruitValues[number]>;
// 如果有枚举成员没加到数组里,下面的类型会报错
type EnsureAllMembersIncluded = AllFruitMembers extends never ? true : false;

新增枚举项时,必须同步更新fruitValues数组,否则类型校验会报错,能有效避免遗漏。

方案2:利用类型元组推导枚举大小

通过TypeScript的类型工具把枚举的联合类型转为元组,推导元组的长度类型,再映射到运行时:

const enum Fruit {
  Apple = 1,
  Banana,
  Carrot,
  Dragonfruit
}

// 把枚举转为联合类型
type FruitUnion = Fruit;

// 类型工具:将联合类型转为元组
type UnionToTuple<T, Acc extends unknown[] = []> =
  Exclude<T, Acc[number]> extends never 
    ? Acc 
    : UnionToTuple<T, [...Acc, Exclude<T, Acc[number]>]>;

// 推导元组的长度,也就是枚举成员数量
type FruitSize = UnionToTuple<FruitUnion>['length'];

// 运行时获取大小,类型会校验数值是否匹配
const FRUIT_SIZE = 4 as FruitSize;

当枚举新增成员时,FruitSize会自动更新为新的长度,如果手动写的数值和类型不匹配,编译会报错,保证正确性。

方案3:构建时生成大小常量

如果是大型项目,可以在构建流程中添加一个脚本,读取TypeScript文件中的const enum定义,解析并计算成员数量,自动生成一个包含大小常量的文件。比如用ts-morph这类工具来解析TS代码,避免手动维护的麻烦。

内容的提问来源于stack exchange,提问作者Ryan Peschel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 03:35:16