microsoft / microsoft/TypeScript

Allow calls to overloaded functions when all possible combinations of union type parameters resolve to valid overloads

Open
#17,471 18 comments 6 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

In Discussion Suggestion
Dominant language
Go
Stars
111k
Forks
14.3k
Avg merge
2d 4h
Merged PRs (30d)
132

Description

TypeScript Version: 2.4.1

Code

Case 1

// overloaded functions
declare function f(a: number): number;
declare function f(a: string): string;

function g<T extends number | string>(a: T) {
    return f(a); // either of arguments is acceptable
//           ~
// Argument of type 'T' is not assignable to parameter of type 'string'.
//  Type 'string | number' is not assignable to type 'string'.
//    Type 'number' is not assignable to type 'string'.
}

Case 2

declare function f2<T>(a: Promise<T>): number;
declare function f2<T>(a: T): string;

function g2<T>(a: T) {
    const result: string = f2(a); // first overload is ignored, but the argument can be a Promise
    return result;
}

Expected behavior:

Case 1: compiles with no errors
Case 2: error that type string | number is not assignable to type string

Actual behavior:

Case 1: error

Argument of type 'T' is not assignable to parameter of type 'string'.
  Type 'string | number' is not assignable to type 'string'.
    Type 'number' is not assignable to type 'string'

Case 2: compiles without errors

Note

I remember here were some discussions about that, so that verifying all possible paths may result in N*M complexity (N overloads, M constituent types in unions). I could not find it.

The second case seems unsafe at all, because skips a possibly valid overload which may effect on return type. I expect that f2(a) would be of type number | string because either of these two overloads can play. It actually has the same result with a: any.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Reproduce both snippets from the issue using TypeScript 2.4.1 and compare their current diagnostics and inferred return types. Investigate overload resolution for generic and union-typed arguments; done means Case 1 compiles while Case 2 reports that string | number is not assignable to string.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
compilers
Issue type
Bug
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Clearly specified
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.