我有一个像这样定义的枚举
export enum someEnum {
None = <any>'',
value1 = <any>'value1',
value2 = <any>'value2',
value3 = <any>'value3'
}
例如,我想检查枚举中是否存在“value4”。我应该得到假,因为在枚举中没有定义value4。
我尝试了if (someEnum['value4'])
但是得到错误 - 元素隐式具有“任意”类型,因为索引表达式不是“数字”类型。
答案 0 :(得分:13)
您可以使用in
运算符:
if ('value4' in someEnum) {
// ...
}
答案 1 :(得分:10)
对于目标为es2017或更高版本的TypeScript 3.7
enum EList {
ITEM_FOO = 'fooData',
ITEM_BAR = 'barData'
}
const lookingForKey = 'ITEM_BAR'
const lookingForValue = 'barData'
// test if `lookingForKey` exists within `EList`
console.log(Object.keys(EList).some((v) => v === lookingForKey))
// test if `lookingForValue` exists within `EList`
console.log(Object.values(EList).some((v) => v === lookingForValue))
答案 2 :(得分:1)
Typescript枚举有点烦人,因为它们有两个方面-用于命名值的原子和实际值。这些都有不同的检查方式。
让我们使用一个示例枚举,该枚举表示内容阻止程序可以执行的操作。我们将从API中获取一个kebab-case值,但想在TS中使用camelCase值:
enum ActionType {
block = "block",
cssDisplayNone = "css-display-none",
ignorePreviousRules = "ignore-previous-rules"
}
现在,如果我们想检查代码中说ActionType.cssDisplayNone
是否有效,我们可以使用in
运算符进行检查。但是,如果我们从API中获得一个值,并且想查看所获得的值是否为ActionType
,那将是行不通的!
const canBlockCss = 'cssDisplayNone' in ActionType; // Returns true
const isValidAction = 'css-display-none' in ActionType; // Returns false!
在这种情况下,我们需要编写一个type guard:
function isActionType(test: any): test is ActionType {
return (Object.values(ActionType).indexOf(test) !== -1);
}
const isValidAction = isActionType('css-display-none') // Returns true
这具有额外的好处,如果您具有未知类型的变量并将其传递给类型保护,则返回值将包含在Typescript对变量的理解中,从而允许您在检查的同时进行转换它。
答案 3 :(得分:0)
要了解如何检查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
卫队。请注意,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
答案 4 :(得分:0)
对于基于字符串的枚举,您想根据枚举的右侧检查值,这是我发现的最简洁的:
Object.values(someEnum).includes('value4')
这需要 ES2017。