Once again I'm here seeking for some guidance on Typescript heuristics. I'm having trouble writing a type guard because Typescript wants to be too narrow when it comes to comparing.
Consider the following scenario (or the Typescript Playground):
const FOO = 'foo' as const;
const BAR = 'bar' as const;
const ALL_THINGS = [FOO, BAR];
type AllThingsType = typeof ALL_THINGS[number];
function isAllThings(value: unknown): value is AllThingsType {
return typeof value === 'string' && ALL_THINGS.includes(value);
}
The error will be the following one:
Argument of type 'string' is not assignable to parameter of type '"foo" | "bar"'.ts(2345)
There is technically a way of working around this:
function isAllThingsWorkaround(value: unknown): value is AllThingsType {
return typeof value === 'string' && (ALL_THINGS as string[]).includes(value);
}
Am I missing something in regards to how I should do this? The snippet I shared is a simplified version, you can assume that ALL_THINGS is actually a collection of almost 25 consts. How could I improve this in order to avoid the workaround?
Thanks for the help!
let a: any = value; return typeof value === 'string' && ALL_THINGS.includes(a);stringdefeats the purpose. It should be perfectly safe to search for astringin an array of string literal types, but TypeScript doesn't let you do it, which is the topic of ms/TS#26255.