Skip to content

Overload/implementation compatibility forces users to use default to 'any' return type #5350

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
WreckedAvent opened this issue Oct 21, 2015 · 2 comments
Labels
Duplicate An existing issue was already created

Comments

@WreckedAvent
Copy link

To be illustrative of the issue, imagine a toy class:

class Test {
    something(x: number): number;
    something(x: string): string;
    something(x: number | string) {
        if (typeof x === "number") {
            return x * 2;
        } else {
            return x + ' is a string';
        }
    }
}

This will not compile, since it is unable to find the best common type between 'number' and 'string'. If modified like this:

    something(x: number | string): number | string {
        if (typeof x === "number") {
            return x * 2;
        } else {
            return x + ' is a string';
        }
    }

then the earlier defined overload fails, saying it is not compatible with the signature of the implementation function.

The only way it seems like you can get this to compile is by simply defining it as any:

    something(x: number | string): any {
        if (typeof x === "number") {
            return x * 2;
        } else {
            return x + ' is a string';
        }
    }

This now compiles, but now we have lost any benefit from being in the typescript world, since my implementation could just as easily do this:

    something(x: number | string): any {
        return { some: 'object' };
    }

Is there a way around this or some solution I'm not seeing?

Note: I am aware that this can be typed without overloads at all, using union types, but this does not really satisfy to me, since the calling code will have to do typeof checks or a typecast.

@xLama
Copy link

xLama commented Oct 21, 2015

Consider this example:

var foo : (x: number) => number;
var bar : (x: number | string) => number | string;

foo = bar; // Error number | string is not assignable to number
bar = foo; // Ok. number is assginable to number | string.

/*

A union type U is assignable to a type T if each type in U is assignable to T.
A type T is assignable to a union type U if T is assignable to any type in U.

*/

@DanielRosenwasser DanielRosenwasser changed the title Poor type safety with function overloads and their implementation Overload/implementation compatibility forces users to use default to 'any' return type Oct 21, 2015
@DanielRosenwasser
Copy link
Member

#943 tracks brainstorming a solution for this.

@DanielRosenwasser DanielRosenwasser added the Duplicate An existing issue was already created label Oct 21, 2015
@microsoft microsoft locked and limited conversation to collaborators Jun 19, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Duplicate An existing issue was already created
Projects
None yet
Development

No branches or pull requests

3 participants