I have the following example code:
type actionT =
| {
name: "action1";
method: (params: { x: number }) => void;
params: { x: number };
}
| {
name: "action2";
method: (params: { y: string }) => void;
params: { y: string };
};
const x: actionT = {
name: "action1",
method: (params) => {
console.log("Got", params.x);
},
params: { x: 12 },
};
const y: actionT = {
name: "action2",
method: (params) => {
console.log("Got", params.y);
},
params: { y: "hi" },
};
const run_action_1 = (action: actionT) => {
switch (action.name) {
case "action1": {
action.method(action.params);
break;
}
case "action2": {
action.method(action.params);
break;
}
}
};
const run_action_2 = (action: actionT) => {
action.method(action.params); // Typescript Error
};
run_action_1(x); // Works
run_action_1(y); // Works
run_action_2(x); // Does not work
run_action_2(x); // Does not work
I understand why it does not work. However, I am looking for a way to make it work other than wrapping it in a switch case with identical function call. That is because in my actual code I have a lot of actions.
The error I am seeing is:
Argument of type '{ x: number; } | { y: string; }' is not assignable to parameter of type '{ x: number; } & { y: string; }'.
Type '{ x: number; }' is not assignable to type '{ x: number; } & { y: string; }'.
Property 'y' is missing in type '{ x: number; }' but required in type '{ y: string; }'.
CodePudding user response:
Wouldn't a generic suit your needs ?
type actionT<T = any> = {
name: "action";
method: (params: T) => void;
params: T;
}
const x: actionT<{ x: number }> = {
name: "action",
method: (params) => {
console.log("Got", params.x);
},
params: { x: 12 },
};
const y: actionT<{ y: string }> = {
name: "action",
method: (params) => {
console.log("Got", params.y);
},
params: { y: "hi" },
};
const run_action_2 = (action: actionT) => {
action.method(action.params);
};
run_action_2(x);
run_action_2(x);