Usually I can master most of typescript language's features, but function overloading sometimes is still quite challenging.
I can't get my head around to why typescript compiler keeps throwing error TS2394: Overload signature is not compatible with function implementation
on the following code (mcve):
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;
}
}
The only difference lies on the 2nd argument: either string
or (substring: string, ...args: any[]) => string
.
Why can't the compiler just mend them together as string | (substring: string, ...args: any[]) => string
?
The last signature is the implementation signature and must be compatible with all overloads. In this case Editor
defines just one public signature, the one with string
and the implementation signature is the one with the callback. This was probably not your intention, you probably wanted both signatures to be available:
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;
}
}
As to why the compiler can't just stich together the implementation signature, overload vs implementation signature difference can get pretty big (with the implementation signature sometimes just using any
for everything), It was probably considered best to allow the developer to choose the implementation signature with a minimal compatibility check to prevent accidental mistakes.