如何根据参数的值缩小函数内的签名范围?

问题描述 投票:0回答:1

我试图将接口的方法组合成一个带有附加

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
应该能够反映这一点。

typescript
1个回答
1
投票

您可以选择:

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);

请参阅如何根据另一个函数参数的缩小类型来推断/缩小函数参数类型?了解详细讨论

© www.soinside.com 2019 - 2024. All rights reserved.