I can write a non-generic type guard to check if a given string is a member of a string enum like this:
enum MyEnum {
Thing1 = 'thing one',
Thing2 = 'thing two',
}
const isMyEnum = (token: any): token is MyEnum => {
return Object.values(MyEnum).includes(token as MyEnum);
};
Is it possible to make this generic, so that I could re-use the same checking logic for many different string enums?
TS string enums and number enums have very different JS emits.
The accepted answer works for OP's case of string enums.
But someone using number enums may naively think that it will also work for their use case. Be careful.
//number enum here
enum E {
A,
B,
C,
}
const isSomeEnum = <T>(e: T) => (token: any): token is T[keyof T] =>
(Object as any).values(e).includes(token as T[keyof T]);
console.log(isSomeEnum(E)("A")); //expected false, actual true
console.log(isSomeEnum(E)(0)); //expected true , actual true
function isSomeEnum2<T> (e: T) : (token: unknown) => token is T[keyof T] {
const keys = Object.keys(e)
.filter((k) => {
return !/^\d/.test(k);
});
const values = keys.map((k) => {
return (e as any)[k];
});
return (token: unknown): token is T[keyof T] => {
return values.includes(token);
};
};
console.log(isSomeEnum2(E)("A")); //expected false, actual false
console.log(isSomeEnum2(E)(0)); //expected true , actual true
Playground
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With