我有一个字符串枚举类型,如:
export enum UserRole {
admin = "admin",
active = "active",
blocked = "blocked"
}
我要检查某些字符串是emule还是不是怎么做?
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.
如何做到?
答案 0 :(得分:1)
Javascript没有枚举的概念,因此不可能。在编译时,typescript将枚举定义转换为您日常使用的普通Javascript对象。没有有关Enum的信息保留供您检查。
所以下面的这个枚举定义
enum UserRole {
admin = "admin",
active = "active",
blocked = "blocked"
}
将被翻译成这样
var UserRole;
(function (UserRole) {
UserRole["admin"] = "admin";
UserRole["active"] = "active";
UserRole["blocked"] = "blocked";
})(UserRole || (UserRole = {}));
答案 1 :(得分:1)
我通常远离enum
,因为它们是少数几个违反TypeScript's own language design goals的TypeScript功能之一:它们不是JavaScript的一部分,但可以编译为JavaScript。这意味着我们不能轻易指出运行时会发生什么情况的JavaScript规范。
无论如何,似乎您对enum
的运行时行为感兴趣,而不一定对它们的类型系统行为感兴趣,因此在接下来的内容中,我将担心在运行时而不是在编译器中回答您的问题。在运行时,enum
只是具有键和值的对象。只要您使用的是string enum,键和值就将与您设置的键和值相同。
(如果您使用的是numeric enum,还会在reverse mappings处将值添加为键,并将键添加为值。这会造成额外的混乱,但似乎应用于您的问题,因此除非有更多详细信息,否则我将避免谈论它。)
您已经将enum
的键和值设置为相同,这导致了我想避免的歧义。我将像这样重新定义UserRole
:
enum UserRole {
ADMIN = "admin",
ACTIVE = "active",
BLOCKED = "blocked",
}
现在,我们可以显示问题“此字符串是否为枚举的键”和“此字符串是否为枚举的值”之间的区别。无论如何,假设我们有一个字符串role
,并且想看看它是否是枚举的键,我们可以这样做:
const roleIsEnumKey = role in UserRole;
console.log("role " + role + (roleIsEnumKey ? " IS " : " IS NOT ") + "a key in UserRole");
如果我们想查看它是否是枚举的值,可以执行以下操作:
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()
或您想要的任何其他方法。
让我们看看它是否有效:
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
只是一个对象,您可以像对待任何对象一样检查其键和值。
答案 2 :(得分:0)
正如@NearHuscarl所说,无法检查。
但是,您可以检查djson.role (string)
是否是UserRole (enum)
值之一:
!!(Object.values(UserRole).find(enumValue => enumValue === djson.role)));
答案 3 :(得分:0)
enum
的值可以是字符串或数字。因此,测试的唯一方法是针对字符串或数字进行测试。
我们可以先创建一个User-Defined Type Guard,如下所示:
function isInstance<T extends object>(value: string, type: T): type is T {
return Object.values(type).includes(value)
}
如果在枚举中找到该值,则返回true或false(这不适用于数字或具有相同字符串的枚举)。
enum Animal {
Cat = 'cat',
Dog = 'dog'
}
enum Plant {
Tree = 'tree',
Flower = 'flower'
}
function isInstance<T extends object>(value: string | number, type: T): type is T {
return Object.values(type).includes(value)
}
console.log(isInstance('dog', Animal)) // True
console.log(isInstance('dog', Plant)) // False