再次:打字稿函数重载

Once again: typescript function overload

通常我可以掌握大多数typescript语言的特性,但函数重载有时还是比较有挑战性的。

我无法理解为什么 typescript 编译器在以下代码 (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 一样将它们一起修补?

最后一个签名是实现签名,必须与所有 重载兼容。在这种情况下,Editor 只定义了一个 public 签名,带有 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),可能是考虑到了最好允许开发人员选择具有最少兼容性检查的实现签名,以防止意外错误。