When working with TypeScript, I've utilized a generic JSON type as suggested in this source:
type JSONValue =
| string
| number
| boolean
| null
| JSONValue[]
| {[key: string]: JSONValue}
My goal is to cast interface types matching JSON to and from the JSON type. For instance:
interface Foo {
name: 'FOO',
fooProp: string
}
interface Bar {
name: 'BAR',
barProp: number;
}
const genericCall = (data: {[key: string]: JSONValue}): Foo | Bar | null => {
if ('name' in data && data['name'] === 'FOO')
return data as Foo;
else if ('name' in data && data['name'] === 'BAR')
return data as Bar;
return null;
}
Unfortunately, TypeScript currently raises an error because it doesn't recognize how the interface could match JSONValue:
Conversion of type '{ [key: string]: JSONValue; }' to type 'Foo' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first.
Property 'name' is missing in type '{ [key: string]: JSONValue; }' but required in type 'Foo'.
However, logically we know that at runtime types Foo and Bar are indeed compatible with JSON. So, how can I convince TypeScript that this casting is valid?
ETA: While I can follow the error message and cast to unknown first, I prefer not to do that -- I'd like TypeScript to understand the distinction. Is that achievable?