Skip to content
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

Dissallow same parameter signature in overloads #13612

Closed
tinganho opened this issue Jan 21, 2017 · 6 comments
Closed

Dissallow same parameter signature in overloads #13612

tinganho opened this issue Jan 21, 2017 · 6 comments
Labels
Duplicate An existing issue was already created

Comments

@tinganho
Copy link
Contributor

tinganho commented Jan 21, 2017

I think the below overloads are ambiguous:

namespace Greet {
    export function sayHi(): number
    export function sayHi(): string
    export function sayHi(): string | number {
        if (Math.random() > 0.5) {
            return '';
        }
        else {
            return 1;
        }
    }
}

// What 
typeof Greet.sayHi(); // What is the type?

Since, we are selecting a return type based on the parameter signature. But, what if the parameter signature is the same on multiple overloads? Nowadays, if the checker cannot find an appropriate overload it takes the first one. I think this is quite an unsafe approach. In the above example, it is clear that sayHi() cannot be narrowed to either string or number based on parameter signature selection, since there is only one parameter signature (), and thus should have the return type string | number only.

What I propose, is to error on the overload that has the same parameter signature:

namespace Greet {
    export function sayHi(): number // Error: Multiple same parameter signature on overload
    export function sayHi(): string // Error: Multiple same parameter signature on overload
    export function sayHi(): string | number {
        if (Math.random() > 0.5) {
            return '';
        }
        else {
            return 1;
        }
    }
}
``
@alitaheri
Copy link

There is something else involving generics:

function sayHi<T extends string>(): T;
function sayHi<T extends object>(): keyof T;
function sayHi(): string { ... }

it can match conditionally by type even without using inference:

sayHi<'a'>(); // 'a'
sayHi<{b: number}>(); // 'b'

If the compiler should enforce that it should keep this behavior intact. Generic constraints contribute identity to the signature.

In other words it should only complain when it sees indistinguishable overloads (overloads ONLY different in their return type). Not having this rule enforced haven't got me into trouble so far though.

@tinganho
Copy link
Contributor Author

I was thinking about type parameter as well, though didn't give an example on it.

paramater signature = type parameter signature + value parameter signature 

@tinganho
Copy link
Contributor Author

tinganho commented Jan 21, 2017

I think this one is also required for #6606. Since, the following expression is ambiguous:

typeof Greet.sayHi();

@gcnew
Copy link
Contributor

gcnew commented Jan 21, 2017

#13225 is in a similar vein.

@HerringtonDarkholme
Copy link
Contributor

HerringtonDarkholme commented Jan 22, 2017

Just for your information, the proposed behavior is implemented in pre TS1.1. But it is removed in later releases.

http://stackoverflow.com/questions/25022331/overloads-cannot-differ-only-by-return-type

Also, the spec disallows same parameter signature in ambient function declaration.

@mhegazy
Copy link
Contributor

mhegazy commented Jan 23, 2017

Duplicate of #13225

@mhegazy mhegazy added the Duplicate An existing issue was already created label Jan 23, 2017
@mhegazy mhegazy closed this as completed Apr 21, 2017
@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

5 participants