再次:打字稿函数重载

时间:2019-02-11 00:16:06

标签: typescript typescript-types

通常,我可以掌握打字稿语言的大多数功能,但是有时函数重载仍然非常困难。

我无法理解为什么打字稿编译器总是在以下代码(mcve)上抛出error TS2394: Overload signature is not compatible with function implementation

class Editor {
  replace(
    searchValue: { [Symbol.match](string: string): RegExpMatchArray; }, 
    replaceValue: string,
  ): this;

  replace(
    searchValue: { [Symbol.match](string: string): RegExpMatchArray; },
    replacer: (substring: string, ...args: any[]) => string,
  ): this {
    return this;
  }
}

唯一的区别在于第二个参数:string(substring: string, ...args: any[]) => string

为什么编译器不能像string | (substring: string, ...args: any[]) => string一样将它们补齐?

1 个答案:

答案 0 :(得分:1)

最后一个签名是实现签名,并且必须与所有重载兼容。在这种情况下,Editor仅定义一个公共签名,其中一个带有string,而实现签名则是带有回调的签名。这可能不是您的意图,您可能希望两个签名均可用:

class Editor {
    replace(
        searchValue: { [Symbol.match](string: string): RegExpMatchArray; }, 
        replaceValue: string,
    ): this;
    replace(
        searchValue: { [Symbol.match](string: string): RegExpMatchArray; },
        replacer: (substring: string, ...args: any[]) => string,
    ): this
    replace(
        searchValue: { [Symbol.match](string: string): RegExpMatchArray; },
        replacer: string | ((substring: string, ...args: any[]) => string),
    ): this {
    return this;
    }
}

关于为什么编译器不能仅将实现签名拼凑在一起,重载与实现签名的区别可能会变得非常大(实现签名有时只对所有内容使用any),这可能被认为是最好的选择允许开发人员选择具有最小兼容性检查的实现签名,以防止意外错误。