Trying to consolidate interface methods into a single function with an additional operation
parameter. The function can be called as expected, but struggling to narrow the signature within the function. Found some assistance in this SO post, but still encountering issues with args[1]
being considered as possibly undefined
in the "plus"
case:
interface Calculator {
plus: (a: number, b: number) => number;
unaryPlus: (a: number) => number;
}
type CalculateParameters = {
[P in keyof Calculator]: [P, ...Parameters<Calculator[P]>];
}[keyof Calculator];
const calculate = (...[operation, ...args]: CalculateParameters) => {
switch (operation) {
case "plus":
// Object is possibly undefined
return args[0] + args[1];
case "unaryPlus":
return args[0];
default:
throw new Error("Unknown operation.");
}
};
// Working as expected
export const x = calculate("plus", 1, 2);
export const y = calculate("unaryPlus", 1);
Attempted conditional types as recommended here, but required a lot of duplication and casting. Is it feasible to narrow the signature within calculate
without these methods?
P.S. Once the argument typing issue is resolved, now dealing with accurately typing the return value. Calculator
may have functions that return types other than number
, and calculate
should be able to accommodate that.