Sam96
Sam96

Reputation: 1910

Typescript: Overload with optional paramters: "Overload signature is not compatible with function implementation."

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

Answers (2)

Sam96
Sam96

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

Titian Cernicova-Dragomir
Titian Cernicova-Dragomir

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

Related Questions