Repository: TypeScript
Issue: Overload causes generic function to loose type specificity
Labels: Needs Investigation

# Bug Report

<!--
  Please fill in each section completely. Thank you!
-->

### 🔎 Search Terms

<!--
  What search terms did you use when trying to find an existing bug report?
  List them here so people in the future can find this one more easily.
-->

generic overloaded function type narrowing

### 🕗 Version & Regression Information

<!-- When did you start seeing this bug occur?

"Bugs" that have existed in TS for a long time are very likely to be FAQs; refer to
  https://github.com/Microsoft/TypeScript/wiki/FAQ#common-bugs-that-arent-bugs

If possible, please try testing the nightly version of TS to see if it's already been fixed.
For npm: `typescript@next`
This is also the 'Nightly' version in the playground: http://www.typescriptlang.org/play/?ts=Nightly

Note: The TypeScript Playground can be used to try older versions of TypeScript.

Please keep and fill in the line that best applies:
-->
- This is the behavior in every version I tried (4.8, 4.9)

### ⏯ Playground Link

<!--
  A link to a TypeScript Playground "Share" link which shows this behavior

  The TypeScript Workbench can be used for more complex setups, try
  https://www.typescriptlang.org/dev/bug-workbench/

  As a last resort, you can link to a repo, but these will be slower for us to investigate.
-->

https://www.typescriptlang.org/play?#code/FASwdgLgpgTgZgQwMZQAQEFUG9itQgLlQEYBuYAX2FElkRVQCFUoAPaMAEwGcNtdUAIyIAmclRrR4yNAHUYCAA6LYxADwAVFuyhde6AHz88ANwQAbAK5QiG8dXBT6chctgjN2jjwxGcpi2tbe2A4SzAkCBAAezBUcIB3V082b30DAAokpRVOInkc1U0DAEpbUPDImLjE5K1U3R9DLNdc-Nb3YrLUDQqIqNj4sGzFFJ09XxbCvNQCtxh1DSMAH1mOmA8l7q1-VBgoCEsYOJHcgDozKygQpFjuCCEiZgBebHwiYgAaR9QRVApyLcwPdUKcoDM5ioFmpGEZXlhUJcgkJ-tQgSDoPdiKhXrUlFM3JwSqRUAB6UmoTEQYhPVAZW4wfaRErAdEPKl-V4ABRg0QAtiBuFAzvtuNFzCYoATciUzhAABa6DJ4xTEskUjlEHn8wVQNSGOnceXRSzmThCNDagVCmGlVl3dlQe4AZhxqAA2mDOABdM58-EqtXkylOiDOojod3ew3G03mwRoRhRllAA


### 💻 Code

<!-- Please post the relevant code sample here as well-->
```ts

interface A {
  a: 1;
}

interface B extends A {
  b: 2;
}

interface Wrapper1<T extends A> {
  value: T;
}

interface Wrapper2<T extends A> {
  value: T;
}

function unwrap<T extends A>(wrapped: Wrapper1<T>): T
function unwrap<T extends A>(wrapped: Wrapper2<T>): T // Comment out this line, and types will become inferred correctly
function unwrap<T extends A>(wrapped: Wrapper1<T> | Wrapper2<T>): T {
  return wrapped.value;
}

const b: B = { a: 1, b: 2 };
const wrapped: Wrapper1<B> = { value: b }

const test1 = unwrap(wrapped); // test1: B (correct)
const test2 = Promise.resolve(wrapped).then(unwrap); // test2: Promise<A> (should be Promise<B>)
const test3 = [wrapped].map(unwrap); // test3: A[] (should be B[])
```

### 🙁 Actual behavior

In `test2` and `test3`, the generic type of the overloaded function `unwrap` looses it's specificity. The types can be narrowed to `Promise<B>` and `B[]` respectively, but actually it is inferred as `Promise<A>` and `A[]` respectively. Removing the one of the overloads of the function `unwrap` (so it is no longer overloaded) will resolve the problem.

### 🙂 Expected behavior

As explained above, the inferred types of `test2` and `test3` should be inferred as `Promise<B>` and `B[]` respectively.