Repository: TypeScript
Issue: Incorrect(?) type inferred for type parameter that is only used in an irrelevant union branch of a function parameter's type
Labels: Suggestion,Experience Enhancement,Experimentation Needed

# Bug Report

### 🔎 Search Terms

type parameter inferred union branch 

### 🕗 Version & Regression Information

TS >=4.4.4

### ⏯ Playground Link

[Workbench link with relevant code](https://www.typescriptlang.org/dev/bug-workbench/?#code/C4TwDgpgBAYg9nAPANQIYBsCuEB8UC8UA3gFBRQBOEqAJnAHbohSiQBcUA5PHJwNxlK1Oo2YA3DNg5osEAQF8BJVtABCqCikm4CxQVVoMmLcBA6d1FfvuFHx26doVKVsBJcQ8Z2ADRRL3jqEPJ4IgXgAPv4aiAHaOEoAxgwAzsBQAOYQwIG6oXC5hPQQYhAUfnGyusWlFDgAFABm7hocPB5e2hUa4QCUbWHaUFGV2AQ4gs1wlgB0ErJKAPSLUAC06yQkWTna9UQm7Fw8nH7zUlAALABMUPJQqCluSPSYALYARmU4vQLLUAB6AH4SH8AKIAD0giWAEBoUAAlvQ0qh6MB4ag0QwOAADRAvD5lPw1L5NFoUAbTGL4z7lKDEuq9cZ0t407GbbaBPYHMxcSwnKBnHmcVBQNIUREZTi3e6PDxiiXfX4rIEglYQqEwuGI5Go9GY+g4vElQmi4Di+gZBpTSwUjz0vzyi3fJmOjJsoA)

### 💻 Code

```ts
type Foo<Value> = {
  readonly type: 'Foo';
  readonly value: Value;
};

type Bar<Value> = {
  readonly type: 'Bar';
  readonly value: Value;
};

type FooBar<FooValue, BarValue> = Foo<FooValue> | Bar<BarValue>;

const getValue = <FooValue = never, BarValue = never>(fooBar: FooBar<FooValue, BarValue>): FooValue | BarValue =>
  fooBar.value;

// ---

getValue({ type: 'Foo', value: 42 } as Foo<number>);
// Actual instantiation: `<number, number>(fooBar: FooBar<number, number>) => number`
// Expected instantiation: `<number, never>(fooBar: FooBar<number, never>) => number`

getValue({ type: 'Bar', value: 'a string' } as Bar<string>);
// Actual instantiation: `<string, string>(fooBar: FooBar<string, string>) => string`
// Expected instantiation: `<never, string>(fooBar: FooBar<never, string>) => string`
```

### 🙁 Actual behavior

- ```ts
  getValue({ type: 'Foo', value: 42 } as Foo<number>)
  ```
  is instantiated as
  ```ts
  <number, number>(fooBar: FooBar<number, number>) => number
  ```
  
- ```ts
  getValue({ type: 'Bar', value: 'a string' } as Bar<string>)
  ```
  is instantiated as
  ```ts
  <string, string>(fooBar: FooBar<string, string>) => string
  ```

### 🙂 Expected behavior

- ```ts
  getValue({ type: 'Foo', value: 42 } as Foo<number>)
  ```
  should be instantiated as
  ```ts
  <number, never>(fooBar: FooBar<number, never>) => number
  ```
  because, given only a `Foo<number>`, there is no `Bar<T>` branch to infer from, so `BarValue` should fall back to its default of `never`
  
- ```ts
  getValue({ type: 'Bar', value: 'a string' } as Bar<string>)
  ```
  should be instantiated as
  ```ts
  <never, string>(fooBar: FooBar<never, string>) => string
  ```
  because, given only a `Bar<string>`, there is no `Foo<T>` branch to infer from, so `FooValue` should fall back to its default of `never`

### 📰 Remarks

This is some unexpected behaviour that I found a little while ago. I _think_ it's a bug? But it's possible I'm just missing some intuition here. 😅

Strangely, if I change the definitions of `Foo` and `Bar` to use _distinct_ names for their "value" fields, the calls are instantiated as I expected:
[Workbench link with relevant code](https://www.typescriptlang.org/dev/bug-workbench/?#code/C4TwDgpgBAYg9nAPANQIYBsCuEB8UC8UA3gFBRQBOEqAJnAHbohSiQBcUA5PHJwNxlK1Oo2YAzBGiwQOU7AIC+Akq2gAhVBRQZseQqXJVaDJi3AyuGiv0FGRpgEaa5Fl4uWrYCK4h4uANFBWLnpeSH46uFAAPkGaiMGROMoAxgwAzsBQAOYQwC4EUL6SkYX0EABuEBSBidJlldU4ABQScFYcPD4R0rXOSQCUnSX1sXXYBDiCbVYAdJ74i1w8nFAA-FAzmrNtBRxbFLNOFG4kJAD051AAtLdnufmRzURm7MsInIG7kRwALABMUAUUFQ6TCiHomAAtg4mgMBJcoAA9NYXK4AUQAHpAUsAIDQoABLeiZVD0YCE1AUhgcAAGEOhsJqUHKVQoLQOw3a8UhMOqgVZcMmLMZ1Vp9zyLmerwsnCsnygxxcHE4qCgmQoxOyq2BoLiWg1Wpw8LRyNRiKxOLxBOJpPJlOp9DpEMazMN9GyHO8mi5PkFbuAmo9xuF7uy4qAA)