Is there a way to consolidate the methods of an interface into a single function with an additional operation
parameter? Despite being able to call the resulting function as expected, I'm struggling to narrow the return type within the function itself.
While I found the answer to a previous question of mine helpful in narrowing parameter types, the ability to narrow the return type inside the function remains a mystery:
interface Machine {
doSomething: (arg: number) => string;
doSomethingElse: (args: boolean) => number;
};
type MachineParameters = {
[K in keyof Machine]: [K, ...Parameters<Machine[K]>];
}[keyof Machine];
const execute = <T extends MachineParameters>(...args: T): ReturnType<Machine[T[0]]> => {
switch (args[0]) {
case "doSomething":
// Error: Type '`${number}`' is not assignable to type 'MachineReturnTypes[T[0]]'.
return `${args[1]}`;
case "doSomethingElse":
// Error: Type 'number' is not assignable to type 'MachineReturnTypes[T[0]]'.
return Number(args[1]);
default:
throw new Error("Unknown operation");
}
};
// Works: string
const x = execute("doSomething", 1);
// Works: number
const y = execute("doSomethingElse", true);