如何检查Enum中是否存在给定的字符串

时间:2016-11-14 21:41:08

标签: typescript

我有一个像这样定义的枚举

export enum someEnum {
    None = <any>'',
    value1 = <any>'value1',
    value2 = <any>'value2',
    value3 = <any>'value3'   
}

例如,我想检查枚举中是否存在“value4”。我应该得到假,因为在枚举中没有定义value4。

我尝试了if (someEnum['value4'])但是得到错误 - 元素隐式具有“任意”类型,因为索引表达式不是“数字”类型。

5 个答案:

答案 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中是否存在密钥。如果值等于键,但只是偶然地

类型保护确实是一种更可行的解决方案,但也可以通过以下方式进行改进:

  1. 进行一些优化-在这种情况下,简单的for...in就可以了,我们甚至可以省略hasOwnProperty卫队。
  2. 使类型防护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

答案 4 :(得分:0)

对于基于字符串的枚举,您想根据枚举的右侧检查值,这是我发现的最简洁的:

Object.values(someEnum).includes('value4')

这需要 ES2017。