A variation on top of @jcalz answer is just a single and plain function that can be directly used:
const isEnumValue = <T extends { [k: string]: string }>(something: any, enumObject: T): something is T[keyof T] =>
typeof something === 'string' && Object.values(enumObject).includes(something);
As Justin AnyhowStep observed, this function works only on string enums, sot I put the T extends { [k: string]: string }
clause. In this way we havethis behaviour:
enum StringEnum {
A = 'aaa',
B = 'bbb',
}
enum NumberEnum {
A,
B,
}
let a;
if (isEnumValue(a, StringEnum)) {
if (a === 'SOMETHING') {
// compiler complains:
// This condition will always return 'false' since the types 'StringEnum' and '"SOMETHING"' have no overlap.
}
}
if (isEnumValue(a, NumberEnum)) {
// compiler complains:
// 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'.
}