TypeScript重载和可选参数

时间:2017-09-13 15:39:29

标签: typescript overloading

我有一个有一些重载的函数。

function foo(x: number, y: void): void;
function foo(x: number, y: number | string): number;
function foo(x: number, y: any) {
    if (typeof y === "undefined") {
        return;
    }
    return typeof y === "string"
        ? x / parseFloat(y)
        : x / y;
}

我没有使用y的可选参数,而是专门使用void来指定返回值。预期的用例包括使用undefined作为第二个参数调用的用例。

在另一个函数中,我会这样称呼它:

function bar(x: number, y?: number | string) {
    const f = foo(x, y);
    // Some other stuff
}

这会导致以下类型错误:

Argument of type 'string | number | undefined' is not assignable to parameter of type 'string | number'.
  Type 'undefined' is not assignable to type 'string | number'.

我的理解是foo将第二个参数作为string | number | void,并且当bar调用它时,它将被传递string,{{1 }},或number,TypeScript会清楚void的返回值。

达到预期效果的正确方法是什么?

1 个答案:

答案 0 :(得分:1)

编译器无法知道y内的barnumber | string还是undefined,因为两者都是可能的。如果编译器无法解决这个问题,则无法选择正确的重载。您必须为编译器提供更多帮助:

断言y永远不会是undefined

function bar(x: number, y?: number | string) {

    // Picks `function foo(x: number, y: number | string): number;` overload
    const f = foo(x, y!); // Use the non-null assertion operator here.
    // Some other stuff
}

或使用type guards

function bar(x: number, y?: number | string) {

    if (y === undefined) {
        // Picks `function foo(x: number, y: void): void;` overload
        foo(x, y);
    }
    else {
        // Picks `function foo(x: number, y: number | string): number;` overload
        const a = foo(x, y);
    }
    // Some other stuff
}