I typically avoid using enum
s in TypeScript because they are one of the features that do not align with TypeScript's language design goals. They exist outside of JavaScript but compile to JavaScript, making it challenging to refer to a JavaScript spec for runtime behavior.
However, if you're interested in understanding the runtime behavior of enum
s rather than their role in the type system, then we can explore that aspect further. At runtime, an enum
simply functions as an object with keys and values. Specifically, when utilizing a string enum, the keys and values will match the defined key-value pairs.
(In the case of a numeric enum, there are also reverse mappings where the value acts as a key and vice versa. While this might be confusing, it doesn't directly relate to your inquiry so I'll refrain from delving into it unless requested.)
The similarity between the keys and values in your enum
introduces ambiguity that should be avoided. To address this, let's redefine UserRole
as follows:
enum UserRole {
ADMIN = "admin",
ACTIVE = "active",
BLOCKED = "blocked",
}
This enables us to distinguish between whether a given string is a key or value within the enum. For instance, to determine if a provided string role
is a key in the enum, we can employ the following approach:
const roleIsEnumKey = role in UserRole;
console.log("role " + role + (roleIsEnumKey ? " IS " : " IS NOT ") + "a key in UserRole");
Similarly, to ascertain if the string corresponds to a value in the enum, you can use:
const roleIsEnumValue = (Object.values(UserRole) as string[]).includes(role);
console.log("role " + role + (roleIsEnumValue ? " IS " : " IS NOT ") + "a value in UserRole");
Assuming your JavaScript version supports Object.values()
and Array.prototype.includes()
, you can verify the keys and values. Otherwise, feel free to iterate over Object.keys()
or any preferred method.
To test the functionality:
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
Seems effective. Ultimately, at runtime, the enum
behaves like an object, allowing inspection of its keys and values similar to any other object.
Playground link