要了解如何检查enum 中是否存在值,必须了解编译后它会变成什么。它只不过是一个由 IIFE(立即调用函数表达式)填充的旧 JavaScript 对象。
假设您有一个简单的基于字符串的enum:
enum Test {
TEST = "test"
}
编译后的 JavaScript 代码如下所示:
var Test;
(function (Test) {
Test["TEST"] = "test";
})(Test || (Test = {}));
请注意,这样做的结果很简单:
var Test = {
"TEST": "test"
}
显然,in 运算符足以检查 enum 中是否存在密钥。如果值等于键也足够了,但只是偶然。
类型保护确实是一个更可行的解决方案,但也可以通过以下方式进行改进:
- 稍微优化一下 - 一个简单的
for...in 循环就可以了,在这种情况下,我们甚至可以省略 hasOwnProperty 保护。
- 制作类型保护 generic 以实现可重用性。
请注意,val 参数不仅仅是T,而是T 中的一个值(因此T[keyof T]):
function hasA<T>(obj : T, val: any) : val is T[keyof T] {
for(const k in obj) {
if( obj[k] === val ) {
return true;
}
}
return false;
};
Testing 确保一切正常:
var t = "something";
if(hasA(Test,t)) {
t //inferred as "Test"
}
var d = "any";
if( !hasA(Test, d) ) {
d //inferred as "string"
}
console.log( hasA( Test, "something" ) ); //true
console.log( hasA(Test, "anything") ); //false