我试图将接口的方法组合成一个带有附加
operation
参数的函数。可以按预期调用生成的函数,但似乎我无法在函数内缩小签名范围。这个SO问题有点帮助,但编译器仍然认为args[1]
可以是undefined
情况下的"plus"
:
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.");
}
};
// Work as expected
export const x = calculate("plus", 1, 2);
export const y = calculate("unaryPlus", 1);
我按照here的建议尝试了条件类型,但这需要大量的重复和转换。如果没有的话,是否可以将签名缩小到
calculate
之内?
附注一旦解决了参数输入问题,我还面临着正确输入返回值的问题。
Calculator
可以具有返回 number
之外的其他内容的函数,并且 calculate
应该能够反映这一点。
您可以选择:
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 = (...args: CalculateParameters) => {
switch (args[0]) {
case "plus":
// Object is possibly undefined
return args[1] + args[2];
case "unaryPlus":
return args[1];
default:
throw new Error("Unknown operation.");
}
};
// Work as expected
export const x = calculate("plus", 1, 2);
export const y = calculate("unaryPlus", 1);
请参阅如何根据另一个函数参数的缩小类型来推断/缩小函数参数类型?了解详细讨论