原 8 月 18 日
在我的情况下,上述解决方案都不起作用,原因是我将枚举值转换为枚举对象。
在那之后我试图知道枚举是否等同于另一个枚举对象...所以我创建了以下 通用 函数:
public static enumEquals<T>(e: any, e1: T, e2: T): boolean {
const v1 = this.enumValue(e, e1);
return v1 === this.enumValue(e, e2, typeof v1);
}
private static enumValue<T>(enumType: any, value: T, validType?: string) {
let v = enumType[value];
if (!validType) {
return v;
}
while (typeof v !== validType) {
v = enumType[v];
}
return v;
}
这是我的测试用例的一个例子:
enum SomeEnum {
VALUE1, VALUE2, VALUE3, VALUE_DEF
}
const enumRefKey = localStorage.getItem('someKey');
const parsedEnum = SomeEnum[enumRefKey] || SomeEnum.VALUE_DEF;
console.log(parsedEnum);
if (parsedEnum === SomeEnum.VALUE_DEF) {
// do stuff
}
显然代码不起作用,在我尝试了这里给出的解决方案后,我发现当 enumRefKey 有效时 console.log(parsedEnum) 正在打印数字并且文本 VALUE_DEF 不是。使用所有其他解决方案也会出现相同的结果:
- parsedEnum 为 SomeEnum
- parsedEnum.valueOf()
- SomeEnum[parsedEnum]
使用泛型方法的解决方案如下所示:
enum SomeEnum {
VALUE1, VALUE2, VALUE3, VALUE_DEF
}
const enumRefKey = localStorage.getItem('someKey');
const parsedEnum = SomeEnum[enumRefKey] || SomeEnum.VALUE_DEF;
console.log(parsedEnum);
if (this.enumEquals(SomeEnum, parsedEnum, SomeEnum.VALUE_DEF) {
// do stuff
}
更新 SEP/21
在TypeScript 比较中避免与enums 相关的所有问题的最佳方法是像以下示例一样声明它们。
而不是这个:
enum SomeEnum {
VALUE1, VALUE2, VALUE3
}
这样做:
enum SomeEnum {
VALUE1 = 'VALUE1', VALUE2 = 'VALUE2', VALUE3 = 'VALUE3'
}
从现在开始,您无需将枚举值强制转换或转换为枚举对象,并且如果您需要,它将始终有效。使用此解决方案,以下所有示例均有效,它们将返回 true:
console.log(SomeEnum['VALUE1'] === 'VALUE1'); // prints 'true'
console.log(SomeEnum['VALUE1'] === SomeEnum.VALUE1); // prints 'true'
console.log(SomeEnum['VALUE1'] === 'VALUE1' as SomeEnum); // prints 'true'
console.log(SomeEnum['VALUE1'] === 'VALUE1'); // prints 'true'
console.log(SomeEnum['VALUE1'] === (<SomeEnum>'VALUE1')); // prints 'true'
console.log(SomeEnum.VALUE1 === 'VALUE1' as SomeEnum); // prints 'true'
console.log(SomeEnum.VALUE1 === (<SomeEnum>'VALUE1')); // prints 'true'
console.log(SomeEnum.VALUE1 === 'VALUE1'); // prints 'true'
罪魁祸首
所有这些问题的原因是当TypeScript被编译为JavaScript时,枚举被解析为objects这样
// this enum at TS
enum SomeEnum {
VALUE1, VALUE2, VALUE3
}
// is parsed to JS like this:
{
VALUE1: 1, VALUE2: 2, VALUE3: 3, 1: 'VALUE1', 2: 'VALUE2', 3: 'VALUE3'
}
如您所见,一旦枚举被解析为 JS,所有比较问题的原因就很明显了,因为我们可能会错误地将 string 与 number 进行比较,这可能会导致误报结果。以下是解析为 JS 的第二个枚举,效果更好:
// this enum at TS
enum SomeEnum {
VALUE1 = 'VALUE1', VALUE2 = 'VALUE2', VALUE3 = 'VALUE3'
}
// is parsed to JS like this:
{
'VALUE1': 'VALUE1', 'VALUE2': 'VALUE2', 'VALUE3': 'VALUE3'
}