Typescript函数重载“此调用没有重载”

时间:2019-10-16 18:55:49

标签: typescript

我实际上认为这是一个错误,但是我想问一下。我有一个功能。如果传递一个数字,我想执行一个返回两个对象的操作。如果它收到两个数字,我想返回一个对象。现在看起来像这样:

function split (splitAt: number | [number, number]): SomeSplittableObject | [SomeSplittableObject, SomeSplittableObject]

但是在超载的情况下,我应该能够做到这一点:

function split (splitAt: number): [SomeSplittableObject, SomeSplittableObject]
function split (splitAt: [number, number]): SomeSplittableObject
function split (splitAt: number | [number, number]): SomeSplittableObject | [SomeSplittableObject, SomeSplittableObject] {
    // ... Implementation
}

let splitAt: number | [number, number] //... some variable
split(splitAt)

但是我收到编辑器错误

No overload matches this call.
  Overload 1 of 2, '(splitAt: [number, number]): SomeSplittableObject', gave the following error.
    Argument of type 'number | [number, number]' is not assignable to parameter of type '[number, number]'.
      Type 'number' is not assignable to type '[number, number]'.
  Overload 2 of 2, '(splitAt: number): [SomeSplittableObject, SomeSplittableObject]', gave the following error.
    Argument of type 'number | [number, number]' is not assignable to parameter of type 'number'.
      Type '[number, number]' is not assignable to type 'number'.

即使我在实现args中将splitAt转换为any也会收到错误

1 个答案:

答案 0 :(得分:1)

导致您出错的行是这一行:

let splitAt: number | [number, number] //... some variable

使用您拥有的重载签名,就是说您有两种形式的函数split。一个带一个数字,另一个带两个数字的数组。您没有同时使用两种类型的签名,因此编译器会抱怨。

split(1) // return type is [SomeSplittableObject, SomeSplittableObject]
split([1,2]) // return type is SomeSplittableObject

let splitAt: number | [number, number] //... some variable
split(splitAt) // return type is ???

编辑

请注意,当重载函数时,已实现的函数签名会被重载遮盖,并且外部看不到。在上述情况下,您只有2个选项。如果要在输入/输出“含糊不清”的位置添加第三个选项,则需要将签名添加为重载(为清楚起见,在此使用较短的类型):

function foo(x: number): Foo;
function foo(x: string): Bar;
// Define an overload in which the inputs and outputs can be either type
function foo(x: string | number): Foo | Bar;
// Function signature is shadowed by overloads defined above.
function foo(x: string | number): Foo | Bar { /* ... */ }