如何在TypeScript中获取常量枚举的大小?

vmpqdwk3  于 2022-11-30  发布在  TypeScript
关注(0)|答案(2)|浏览(288)

假设我有一个常量枚举,如下所示:

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

这个枚举的大小应该是4。当它不是const枚举时,可以简单地调用类似Object.keys的函数,然后做一些数学运算来得到它的大小。但是,我不认为这对const枚举有效。
人们推荐的另一种方法是包含SIZE参数,如下所示:

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

然后查询Fruit.__SIZE以获得大小。但是,这有两个问题:
1.这个应用程序是网络化的,所以当我最终添加更多的fruit时,另一个fruit将占据__SIZE的位置,因为新的fruit与之前的SIZE / NULL位置具有相同的整数id,这可能会导致问题。
1.必须始终记住将__SIZE值保留在最后,因此它很容易由于程序员忘记保持同步而损坏。
有没有其他的选择呢?因为它只需要在应用程序启动时计算一次,我甚至不介意它是不是很慢。

axzmvihb

axzmvihb1#

const enum的问题是它们被TS编译器编译掉了(参见relevant answer的另一个SO问题)。它在某种程度上陷入了与接口(编译掉)和类(保留为JS代码)相同的限制,即在运行时可能发生的情况。
编译掉的构造的好处是它不会留下代码开销,但是作为结果,它不能用于做出任何运行时决定。(而不是像__SIZE方法那样在编译时执行),您将受益于删除const,接受代码开销,但具有可被评估的结果查找对象。
TypeScriptPlayground-正常
有趣的是,有一个名为preserveConstEnumstsconfig选项,它也能完成这个任务;防止const enum被编译掉,并生成与使用enum时相同的查找对象。然而,令人烦恼的是,这似乎并没有绕过警告,至少在TS游戏场上没有,所以似乎不是一个解决方案。其他人可能会提供一些线索,说明这个选项是否可以在实践中使用。
类型脚本Playground-使用preserveConstEnums

3pvhb19x

3pvhb19x2#

对此我有一个试探性的解决方案,可能对一些人(至少对我)有效。
我的应用程序中有一个数据Map,如下所示:

const dataFruit: Record<Fruit, FruitData> = {
  [Fruit.Apple]: { taste: "yum" },
  [Fruit.Banana]: { taste: "tasty" },
  [Fruit.Carrot]: { taste: "hmm" },
  [Fruit.Dragonfruit]: { taste: "okay" },
}

由于记录的类型,它强制每个Fruit枚举项都在Map中,如果你错过了一个,程序将无法编译(这很好)。
因此,我们现在可以这样做:

const mapSize = Object.keys(dataFruit).length;

获取枚举中的项数。
如果不需要数据Map,我想可以在函数中创建一个无用的数据Map(其中每个值都是数字零),然后使用它来缓存运行时的枚举长度。(函数结束后,临时对象将被垃圾回收),您仍然可以使用const枚举,并且解决方案可以防止您忘记更新大小(由于编译器错误)。

相关问题