检查 TypeScript 中的枚举中是否存在值

IT技术 javascript typescript enums
2021-02-26 22:51:42

我收到一个数字type = 3,必须检查它是否存在于这个枚举中:

export const MESSAGE_TYPE = {
    INFO: 1,
    SUCCESS: 2,
    WARNING: 3,
    ERROR: 4,
};

我发现的最好方法是将所有 Enum 值作为数组获取并在其上使用 indexOf。但是生成的代码不是很清晰:

if( -1 < _.values( MESSAGE_TYPE ).indexOf( _.toInteger( type ) ) ) {
    // do stuff ...
}

有没有更简单的方法来做到这一点?

6个回答

如果您希望它与字符串枚举一起使用,则需要使用,Object.values(ENUM).includes(ENUM.value)因为根据https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-4.html,字符串枚举不是反向映射的

Enum Vehicle {
    Car = 'car',
    Bike = 'bike',
    Truck = 'truck'
}

变成:

{
    Car: 'car',
    Bike: 'bike',
    Truck: 'truck'
}

所以你只需要做:

if (Object.values(Vehicle).includes('car')) {
    // Do stuff here
}

如果您收到以下错误:Property 'values' does not exist on type 'ObjectConstructor',那么您的目标不是 ES2017。您可以使用此 tsconfig.json 配置:

"compilerOptions": {
    "lib": ["es2017"]
}

或者你可以做任何演员:

if ((<any>Object).values(Vehicle).includes('car')) {
    // Do stuff here
}
typescript中的@BBaysinger 试试这个: (<any>Object).values(Vehicle).includes(Vehicle.car)
2021-04-17 22:51:42
Object.values<string>(Enum).includes(value) 为我工作
2021-05-04 22:51:42
这在typescript中不起作用。此外,解决方法在 IE 中提供了中断
2021-05-09 22:51:42
JSONLint 显示Property 'values' does not exist on type 'ObjectConstructor'.
2021-05-12 22:51:42
Object.values(Vehicle).includes('car')但是警告Argument of type 'string' is not assignable to parameter of type 'Vehicle'所以你也必须输入断言
2021-05-14 22:51:42

这仅适用于非常量、基于数字的枚举。对于 const 枚举或其他类型的枚举,请参阅上面的这个答案


如果您使用的是 TypeScript,则可以使用实际的 enum然后你可以使用in.

export enum MESSAGE_TYPE {
    INFO = 1,
    SUCCESS = 2,
    WARNING = 3,
    ERROR = 4,
};

var type = 3;

if (type in MESSAGE_TYPE) {

}

这是有效的,因为当您编译上述枚举时,它会生成以下对象:

{
    '1': 'INFO',
    '2': 'SUCCESS',
    '3': 'WARNING',
    '4': 'ERROR',
    INFO: 1,
    SUCCESS: 2,
    WARNING: 3,
    ERROR: 4
}
是的。只有适当的枚举。
2021-04-19 22:51:42
这不适用于字符串枚举,因为它们没有反向映射: typescriptlang.org/docs/handbook/release-notes/...
2021-04-19 22:51:42
这种方法似乎适用于 2021 年的字符串枚举。
2021-05-07 22:51:42
这仅适用于适当的枚举,对吗?目前它是这样定义的:export const MESSAGE_TYPE = { ... }
2021-05-09 22:51:42
好的,谢谢解释。我会检查为什么我们没有使用正确的枚举,看看我们是否可以改变它。
2021-05-16 22:51:42

根据 Sandersn 的说法,最好的方法是:

Object.values(MESSAGE_TYPE).includes(type as MESSAGE_TYPE)
啊哈!在答案中找到了方法,我可以确认此解决方案有效而没有任何any或类型的抱怨,并且当枚举名称本身与它们各自的实际值不匹配时它有效(因为此页面上的许多hacky解决方案建议或使用)。应该是公认的答案,尤其是最初来自 TypeScript 的 GitHub。
2021-04-26 22:51:42
这适用于您需要检查的每种情况。完美的答案。
2021-05-10 22:51:42
这可能是最好和最安全的答案。它避免使用any. type in MESSAGE_TYPE语法可能会更好,如果你能保证关键和枚举值将是相同的,因为它是一个键查找,而不是一个值查找。
2021-05-11 22:51:42
export enum YourEnum {
   enum1 = 'enum1',
   enum2 = 'enum2',
   enum3 = 'enum3',
}

const status = 'enumnumnum';

if (!Object.values(YourEnum)?.includes(status)) {
     throw new UnprocessableEntityResponse('Invalid enum val');
}
@lukas_o 是对的。这个解决方案乍一看很清楚,但它绝对容易出错。
2021-04-17 22:51:42
我最喜欢这个
2021-04-23 22:51:42
是的,这是一个不好的例子,不应按原样使用。in关键字匹配的密钥,没有value,所以你需要的if语句,如一个更好的解决方案Object.values(YourEnum).includes(status)或ES5的的indexOf解决方案。
2021-04-24 22:51:42
实际上,这种情况只是因为巧合才起作用。'enum1' 只会被找到,因为它与键的值相同。但是如果键与值不同,它就不起作用。
2021-04-29 22:51:42
所以这个例子只是使用 key==value 这就是它起作用的原因,对吧?如果 key!=value,它将通过 key 进行检查。
2021-05-07 22:51:42

您的问题有一个非常简单易行的解决方案:

var districtId = 210;

if (DistrictsEnum[districtId] != null) {

// Returns 'undefined' if the districtId not exists in the DistrictsEnum 
    model.handlingDistrictId = districtId;
}
请注意,如果枚举使用与枚举成员名称不同的值的字符串初始值设定项,则这不适用于字符串枚举。请参阅下面@Xiv 的回答:stackoverflow.com/a/47755096/4752920
2021-04-20 22:51:42
@TimSchoch 我可以确认这至少对于数字枚举非常有效。恕我直言,这是最优雅的解决方案。
2021-04-30 22:51:42
@帕特里克P。你能确认 Ester 提出的解决方案也适用于字符串枚举吗?
2021-05-04 22:51:42
@TimSchoch 是的!它也适用于字符串。就像字典一样 - 您可以对字典中的键使用任何类型。
2021-05-13 22:51:42
谢谢埃斯特的回答。由于我已经从编程转向全职 UX 设计,我无法再验证这一点。@crowd,如果我接受的答案仍然是 2019 年要走的路,请告诉我!干杯
2021-05-14 22:51:42