Reputation: 1910
I've been experimenting with overloads (originally trying to implement this basic proxy example in typescript without foul tricks like disabling type checking on a line, if any of you have solved that feel free to spoiler me, I have already learned much and its getting annoying that I cant seem to solve it).
I've been running into an problem while experimenting. Here's my code:
// "Overload signature is not compatible with function implementation." on first (in code) declaration
function strOrObj (samePar:object, obj:object):object|undefined;
function strOrObj (samePar:object, num:number):number|undefined;
function strOrObj (samePar:object, num?:number, obj?:object):object|number|undefined{
console.log("obj="+obj, "num="+num);
return obj? obj: num;
}
I had to add the undefined
on the implementation because the compiler, looking at the implementation, thought it might be needed. It didnt ask for me to add this to the overrides, but I did it anyways to experiment. But when I add type declarations in the implementation I get the error Overload signature is not compatible with function implementation.
.
The only way I get this to compile is to declare any parameter in the implementation declaration as any
, but that way it'll just stuff every given type into the first optional parameter (num
in this case).
So the queston is, what is wrong here? Is it even possible to have multiple optional parameters if youre not sure the first one will be used or is that maybe the problem (which could be a thing because of the JS implementation)?
Sorry if this is a duplicate, the only thing I could find that seemed to apply was an issue on Github, but the fixes seem to have been merged into the release code.
Upvotes: 4
Views: 4928
Reputation: 1910
@titian-cernicova-dragomir answered my actual answer in the comments of his answer. Here I've written down what I concluded from his answer and my own testing.
Typescript doesnt allow for the name-choosing of given parameters based on their type (without explicitly writing the type check yourself). The only logic overloads implement in Typescript (at least as of now) is a check whether the overloads fit with the implementation in input and return types, and the choice of the fitting override to determine the return type.
The optional variables just get filled from right to left, disregarding the given type. Thats whats causing the error, as even a secondary object parameter ("obj") will end up in the num
variable in the implementation and the compiler complains that the second parameter will never be number, thus that overload signature is invalid.
You can test that by switching the parameters, if you define the obj
first in the implementation it'll complain about the 2nd overload signature, as the 2nd parameter will always be an object.
Upvotes: 0
Reputation: 249796
Typescript allows you to define multiple overloads but it's your job in the implentation to diferentiate between them, this is why the implentation signature must be compatible with all overloads
function strOrObj (samePar:object, obj:object):object|undefined;
function strOrObj (samePar:object, num:number):number|undefined;
function strOrObj (samePar:object, numObj:number| object):object|number|undefined{
if (typeof numObj === 'number') {
return samePar
} else {
numObj
}
}
Upvotes: 6