I’m trying to do something like the following (albeit significantly more complicated):
interface Base {
id: string;
info: object;
}
interface A extends Base {
example: boolean;
}
interface B extends Base {
max: number;
}
interface ActionDataTypes {
'for_a': A;
'for_b': B;
}
function tryAction<A extends keyof ActionDataTypes>(id: string, action: A, data: ActionDataTypes[A]): boolean {
switch(action){
case 'for_a':
//do stuff
break;
case 'for_b':
//do stuff
//this is a more complicated if statement
if(data.max > 12){
//do stuff
}
break;
}
}
TypeScript gives the error Property 'max' does not exist on type 'A | B'. Property 'max' does not exist on type 'A'.
Any thoughts how how to fix it?
These questions did not resolve the issue:
- Typescript type safety in switch case statements
- Typescript does not consider the 'case' of a switch statement as a typeguard?
- Typescript is there a way to cast type for case in switch?
- TypeScript: Type guard does not work with switch statement when putting object into variable
- Why Typescript throw error message: Property does not exist on type?
>Solution :
Currently, the compiler is unable to type-narrow independent arguments, thus I suggest switching to a union of the args using the following mapped type:
// [action: "for_a", data: A] | [action: "for_b", data: B]
type Args = {
[K in keyof ActionDataTypes]: [action: K, data: ActionDataTypes[K]];
}[keyof ActionDataTypes];
And redefined the tryAction
as follows:
function tryAction(id: string, ...args: Args) {}