首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在typescript中检查类型是否为枚举

如何在typescript中检查类型是否为枚举
EN

Stack Overflow用户
提问于 2020-09-05 20:17:01
回答 4查看 89关注 0票数 1

我有一个类似如下的字符串枚举类型:

代码语言:javascript
复制
export enum UserRole {
admin = "admin",
active = "active",
blocked = "blocked"
}

我想检查某些字符串是电动车还是不电动车怎么办?

代码语言:javascript
复制
  const djson = JSON.parse(decode_string)
  if(djson && (djson.role instanceof UserRole) // I just want to check the role is enum string or not. Obviously  this way is wrong.

该怎么做呢?

EN

回答 4

Stack Overflow用户

发布于 2020-09-05 20:43:55

Javascript没有Enum的概念,所以在编译时,typescript不可能将enum定义转换为您日常使用的普通Javascript对象。没有保留有关枚举的信息供您检查。

因此下面的枚举定义

代码语言:javascript
复制
enum UserRole {
    admin = "admin",
    active = "active",
    blocked = "blocked"
}

将被转换为类似下面这样的内容

代码语言:javascript
复制
var UserRole;
(function (UserRole) {
    UserRole["admin"] = "admin";
    UserRole["active"] = "active";
    UserRole["blocked"] = "blocked";
})(UserRole || (UserRole = {}));
票数 1
EN

Stack Overflow用户

发布于 2020-09-05 22:20:22

我通常远离enum,因为它们是为数不多的违反TypeScript's own language design goals的TypeScript特性之一:它们不是JavaScript的一部分,但它们可以编译为JavaScript。这意味着我们不能很容易地指出在运行时发生了什么事情的JavaScript规范。

不管怎样,你似乎对enum的运行时行为感兴趣,而不一定对它们的类型系统行为感兴趣,所以在接下来的内容中,我将考虑在运行时回答你的问题,而不是在编译器中。在运行时,enum将只是一个具有键和值的对象。只要您使用的是string enum,键和值将与您设置的键和值相同。

(如果您使用的是numeric enum,也会有reverse mappings,其中值被添加为键,键被添加为值。这特别令人困惑,但似乎不适用于您的问题,因此除非被追问更多细节,否则我将避免谈论它。)

您已经将enum的键和值设置为相同,这导致了我希望避免的歧义。我将像这样重新定义UserRole

代码语言:javascript
复制
enum UserRole {
    ADMIN = "admin",
    ACTIVE = "active",
    BLOCKED = "blocked",
}

现在我们可以展示问题"is this string a key of the enum“和"is this string a value of the enum”之间的区别。无论如何,假设我们有一个字符串role,我们想看看它是否是枚举的键,我们可以这样做:

代码语言:javascript
复制
const roleIsEnumKey = role in UserRole;
console.log("role " + role + (roleIsEnumKey ? " IS " : " IS NOT ") + "a key in UserRole");

如果我们想看看它是否是枚举的值,我们可以这样做:

代码语言:javascript
复制
const roleIsEnumValue = (Object.values(UserRole) as string[]).includes(role);
console.log("role " + role + (roleIsEnumValue ? " IS " : " IS NOT ") + "a value in UserRole");

假设您使用的是带有Object.values()Array.prototype.includes()的JS版本。如果没有,您可以遍历Object.keys()或任何其他您想要的方法。

让我们看看它是否起作用:

代码语言:javascript
复制
check(JSON.stringify({ role: "ADMIN" }));
// role ADMIN IS a key in UserRole 
// role ADMIN IS NOT a value in UserRole

check(JSON.stringify({ role: "admin" }));
// role admin IS NOT a key in UserRole 
// role admin IS a value in UserRole 

check(JSON.stringify({ role: "random" }));
// role random IS NOT a key in UserRole
// role random IS NOT a value in UserRole 

看起来不错。关键是,在运行时,enum只是一个对象,您可以像检查任何对象一样检查它的键和值。

Playground link

票数 1
EN

Stack Overflow用户

发布于 2020-09-05 22:19:18

正如@NearHuscarl所说的,没有办法检查这一点。但是,您可以检查djson.role (string)是否为UserRole (enum)值之一:

代码语言:javascript
复制
!!(Object.values(UserRole).find(enumValue => enumValue === djson.role)));
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/63753808

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档