An alternative approach to @jcalz's solution is to create a simple function that can be easily utilized:
const checkEnumValue = <T extends { [k: string]: string }>(valueToCheck: any, enumType: T): valueToCheck is T[keyof T] =>
typeof valueToCheck === 'string' && Object.values(enumType).includes(valueToCheck);
As noted by Justin AnyhowStep, this function specifically caters to string enums, hence the
T extends { [k: string]: string }
condition. Here's how it operates:
enum StringEnum {
A = 'aaa',
B = 'bbb',
}
enum NumberEnum {
A,
B,
}
let example;
if (checkEnumValue(example, StringEnum)) {
if (example === 'SOMETHING') {
// Compiler raises an error:
// This condition will always return 'false' since the types 'StringEnum' and '"SOMETHING"' have no overlap.
}
}
if (checkEnumValue(example, NumberEnum)) {
// Compiler raises an error:
// Argument of type 'typeof NumberEnum' is not assignable to parameter of type '{ [k: string]: string; }'.
// Property 'A' is incompatible with index signature.
// Type 'NumberEnum' is not assignable to type 'string'.
}