【问题标题】:Overload method with spread operator not recognized无法识别扩展运算符的重载方法
【发布时间】:2020-08-25 05:30:49
【问题描述】:

我有一个类定义如下:

class Test {
  a(msg: string): string;
  a(msg: string, ...args: unknown[]): string | { msg: string, args: unknown[]} {
    if (args) {
      return { msg: msg, args: args };
    }
    return msg;
  }
}

但是,如果我这样做,我会得到编译错误:

new Test().a("test", "a", 1, 2, 3);

“预期有 1 个参数,但得到了 5 个”

我怎样才能正确地重载这个方法来为不同的签名提供不同的返回类型?

【问题讨论】:

  • 如果你想让重载工作,你需要为所有函数提供相同数量的参数,对于你的行为,最好选择不同的函数名称

标签: typescript overloading


【解决方案1】:

函数实现不是所有可用重载的一部分。相反,你可以写:

class Test {
    a(msg: string): string; // overload 1
    a(msg: string, ...args: unknown[]): { msg: string, args: unknown[] } // overload2
    a(msg: string, ...args: unknown[]): string | { msg: string, args: unknown[] } { // impl
       // ...
    }
}
new Test().a("test", "a", 1, 2, 3); // { msg: string; args: unknown[]; }
new Test().a("test") // string

Playground sample

【讨论】:

  • 感谢您的选择。这让我很感兴趣,因为文档指出overloading with different number of parameters and types with same name is not supported。如果重载 1 和重载 2 的参数数量不同,这如何工作?
  • 如果您指的是其他答案的链接:老实说,文档作者没有很好地解释 TS 中的函数重载并将实现与类型方面混淆。只要坚持official docs - 他们没有说明这一点。如您所见,函数重载是 TS 功能,并且可以具有不同数量的参数。重要的是,函数实现签名与所有重载兼容。您不能多次实现具有相同名称的函数。
  • 顺便说一句:同样的原则适用于方法,如上面的示例。
【解决方案2】:

Typescript 不支持具有不同数量参数的函数重载。

Documentation 说:

TypeScript 提供了函数重载的概念。您可以拥有多个名称相同但参数类型和返回类型不同的函数。但是,参数的数量应该相同。
[...] 不支持具有不同数量的参数和具有相同名称的类型的函数重载。

实现您正在尝试的一个技巧可能是这个

interface ReturnA {
    msg: string;
    args: any[];
}

class Test {

  a(msg: string, ...args: never[]): string;
  a(msg: string, ...args: any[]): ReturnA
  a(msg: string, ...args: any[]): string | ReturnA {
    if (args) return { msg, args };
    return msg;
  }

}

const t = new Test();

// only 1 param returns string
const str: string = t.a(`a`); 

// two or more params returns the other object type
const obj: ReturnA = t.a(`a`, `param1`); 

【讨论】:

  • 感谢您的清晰解释,不知道我是如何在文档中错过的!
  • 我认为您可以尝试使用 never 参数类型来破解您的示例
  • 有趣的破解!输出肯定是我正在寻找的。​​span>
猜你喜欢
  • 1970-01-01
  • 2011-02-05
  • 2022-09-30
  • 2010-09-15
  • 1970-01-01
  • 2015-01-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多