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

Allow Overload Implementaions with no Type Declarations #26701

Closed
4 tasks done
Tiedye opened this issue Aug 27, 2018 · 4 comments
Closed
4 tasks done

Allow Overload Implementaions with no Type Declarations #26701

Tiedye opened this issue Aug 27, 2018 · 4 comments
Labels
Duplicate An existing issue was already created

Comments

@Tiedye
Copy link

Tiedye commented Aug 27, 2018

Search Terms

overload overlap

Suggestion / Example

When overloading a function, there will often be times when you have multiple overloads with different lengths and types the union of which will (unfortunately) create a signature that is a strict super-set of the the previous signatures. For example:

function f(a: number): void;
function f(a: string, b: string): void;
function f(a: string | number, b?: string) {
  // do something
}

This allows a call like f(1, 'a') to pass the type checker. This has the side effect of making it so type-guards in the function implementation can't make super intelligent deductions, for example:

function f(a: number): void;
function f(a: string, b: string): void;
function f(a: string | number, b?: string) {
  if (typeof a === 'number') {
    // `a` is a string but `b` is still `string | undefined`
  }
}

It would be fantastic if we could do something like this:

function f(a: number): void;
function f(a: string, b: string): void;
function f(a, b) {
  if (typeof a === 'number') {
    // `a` is a string and `b` is thus `undefined`
  }
}

What would be happening here is the implementation would not be considered one of the overload signatures, so this would fix the earlier problem of the general signature allowing invalid argument combinations, and the typecheceker would be able to make better deductions about the types arguments.

To preserve compatibility with implicit any, if the feature was only available when noImplicitAny is enabled it would be completely backwards compatible as it would only kick in when there were no type arguments on an overloaded constructor/method/function (right now this is an error).

Use Cases

There are ample examples of overloaded functions, this would allow the typechecker to better do its job when using. As it is now there are often times when unnecessary type checks and assertions are required get it to behave correctly.

Checklist

My suggestion meets these guidelines:

  • This wouldn't be a breaking change in existing TypeScript / JavaScript code
  • This wouldn't change the runtime behavior of existing JavaScript code
  • This could be implemented without emitting different JS based on the types of the expressions
  • This isn't a runtime feature (e.g. new expression-level syntax)
@yortus
Copy link
Contributor

yortus commented Aug 28, 2018

Here's your original example in the playground - note the f(1, 'a') call does error as you would like it to.

EDIT: ...but, right, it doesn't do extra type narrowing inside the function body as you are suggesting.

@Tiedye
Copy link
Author

Tiedye commented Aug 28, 2018

Yeah I thought it used to do it, must have got confused by it externally narrowing the signature correctly.

@RyanCavanaugh
Copy link
Member

Disregarding initial confusion about the implementation signature being visible, seems like a duplicate of #22609 ?

@DanielRosenwasser DanielRosenwasser added the Duplicate An existing issue was already created label Aug 28, 2018
@Tiedye
Copy link
Author

Tiedye commented Aug 28, 2018

Yeah it is, should have searched for overload narrowing. Sorry

@Tiedye Tiedye closed this as completed Aug 28, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Duplicate An existing issue was already created
Projects
None yet
Development

No branches or pull requests

4 participants