假设我有一个常量枚举,如下所示:
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
值保留在最后,因此它很容易由于程序员忘记保持同步而损坏。
有没有其他的选择呢?因为它只需要在应用程序启动时计算一次,我甚至不介意它是不是很慢。
2条答案
按热度按时间axzmvihb1#
const enum
的问题是它们被TS编译器编译掉了(参见relevant answer的另一个SO问题)。它在某种程度上陷入了与接口(编译掉)和类(保留为JS代码)相同的限制,即在运行时可能发生的情况。编译掉的构造的好处是它不会留下代码开销,但是作为结果,它不能用于做出任何运行时决定。(而不是像
__SIZE
方法那样在编译时执行),您将受益于删除const
,接受代码开销,但具有可被评估的结果查找对象。TypeScriptPlayground-正常
有趣的是,有一个名为
preserveConstEnums
的tsconfig
选项,它也能完成这个任务;防止const enum
被编译掉,并生成与使用enum
时相同的查找对象。然而,令人烦恼的是,这似乎并没有绕过警告,至少在TS游戏场上没有,所以似乎不是一个解决方案。其他人可能会提供一些线索,说明这个选项是否可以在实践中使用。类型脚本Playground-使用preserveConstEnums
3pvhb19x2#
对此我有一个试探性的解决方案,可能对一些人(至少对我)有效。
我的应用程序中有一个数据Map,如下所示:
由于记录的类型,它强制每个
Fruit
枚举项都在Map中,如果你错过了一个,程序将无法编译(这很好)。因此,我们现在可以这样做:
获取枚举中的项数。
如果不需要数据Map,我想可以在函数中创建一个无用的数据Map(其中每个值都是数字零),然后使用它来缓存运行时的枚举长度。(函数结束后,临时对象将被垃圾回收),您仍然可以使用const枚举,并且解决方案可以防止您忘记更新大小(由于编译器错误)。