我通常远离 enums,因为它们是少数几个违反 TypeScript's own language design goals 的 TypeScript 功能之一:它们不是 JavaScript 的一部分,但它们编译为 JavaScript。这意味着我们不能轻易地指出运行时发生的事情的 JavaScript 规范。
无论如何,您似乎对enums 的运行时行为感兴趣,而不一定对它们的类型系统行为感兴趣,所以接下来我会担心在运行时而不是在编译器中回答您的问题。在运行时,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 只是一个对象,您可以像使用任何对象一样检查它的键和值。
Playground link