Repository: TypeScript
Issue: Control flow analysis for dependant parameters does not work with complex types
Labels: Suggestion,Help Wanted,Experience Enhancement

# Bug Report

<!--
  Please fill in each section completely. Thank you!
-->

### 🔎 Search Terms

```
dependant parameters
discriminated union parameters
```

### 🕗 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:
-->

TypeScript 4.6.x -> TypeScript 4.9.3 & Nightly

- This is the behavior in every version I tried, and I reviewed the FAQ

### ⏯ 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.
-->
[Playground link with relevant code](https://www.typescriptlang.org/play?ts=4.9.3#code/C4TwDgpgBAglC8UDeAoK6oGsCWA7AJgFxQBEAhiQNwoC+KKokUAQgsmhjgcSQEZW16jaADEArrgDGbABQA6BWQBOAcwDOxANowANFFxiAtrwhKAulAA+UTcz1rgSvCrMBKBAD4oANwD22fGoUSV9cBygAMwBGYnEpWSQsPHwoGj0wMhAAG18yfHd4L1QMKGwIqBkuFPga0gp3YpKMDOzc-DlgXxFsAA8IfBlXSnQAehGoAHIWnLyJ-WUlXwB3fqhOyYNjUwmOdDoSsoqqhFq+Egbdpum2jt8AVTBIJQBhMjUIQeGoMcnr2fmlIsVil1hMHE5cCodiU6DQgtEZIkqjwKKk9AAWABMQxQCKRyR4-DRpAAFhAsjlzpQgA)

### 💻 Code

The release notes for 4.6 explain how [control flow analysis for dependant parameters](https://devblogs.microsoft.com/typescript/announcing-typescript-4-6/#control-flow-analysis-for-dependent-parameters) can work for functions whose arguments are defined as tuples:

```typescript
type Func = (...args: ["a", number] | ["b", string]) => void;

const f1: Func = (kind, payload) => {
    if (kind === "a") {
        payload.toFixed();  // 'payload' narrowed to 'number'
    }
    if (kind === "b") {
        payload.toUpperCase();  // 'payload' narrowed to 'string'
    }
};

f1("a", 42);
f1("b", "hello");
```

However, as soon as you use a more complex type, the code no longer compiles:

```typescript
type A = { kind: "a"; }
type B = { kind: "b"; }

type Func = (...args: [A, number] | [B, string]) => void;

const f1: Func = ({ kind }, payload) => {
    if (kind === "a") {
        payload.toFixed();  // 'payload' should be narrowed to 'number'
    }
    if (kind === "b") {
        payload.toUpperCase();  // 'payload' should be narrowed to 'string'
    }
};

f1({ kind: "a" }, 42);
f1({ kind: "b" }, "hello");
```

### 🙁 Actual behavior

On the line with `payload.toFixed()`, TypeScript gives the following compiler error:

```
Property 'toFixed' does not exist on type 'string | number'.
  Property 'toFixed' does not exist on type 'string'.
```

On the line with `payload.toUpperCase()`, TypeScript gives the following compiler error:

```
Property 'toUpperCase' does not exist on type 'string | number'.
  Property 'toUpperCase' does not exist on type 'number'.(2339)
```

### 🙂 Expected behavior

I would expect TypeScript to apply the same control flow analysis for the more complex typed parameters as the simple ones. I'm actually trying to use this feature while [playing around](https://www.staging-typescript.org/play?target=9&ts=5.0.0-pr-50820-31#code/C4TwDgpgBAcg9gZRAWwEZwDYHkBODgCGwAlgMYA8AKgHxQC8UlUAZFAN5QDOhJpAXFABmBDJwgBuKADsCyCAO45iUgOZQAvuIBQoSFACiGCHKnAAwhgKdOCCMGAQc9KAApgAC2KcBh4xFMANFAAbgIArlIA1lJwAO5SAJT0tMFwxAAm2jrg0ACC9jgAIhCkcDhEZQBiEaQkcFLOLlpQUAB07QQ4Kt7NLVAAPlAA2r4m5pbWtvaOQfBIaJi4+ERk5BZWNnYORSVlFThm9Q4AHsDUALq9LYNDV30t69a5pKQQ1mXFpeXAZZSdKnZyKN-MAghFonEpNQAnd7nMUOhsHgeKtHpxnq93jsvvtDqYIKdobCoJcknRaMDTGiptsBlA0Ri3pwPrtvmUAEpvMIYYBAoxjMFRGLxahZFqlKTcKBwVBiHDBCDpfLAJSoMIOTjOKQQWJQKYuBLacX1KViaY4TUMbW6gCyBDA5EUyhUQWqUlqxHq1ANWQlUqIKoEyuxex+ODdHvqzkENTqDTc-zsQQ4kWU6SCMjkGiSbF6MrlCqVBWIao1rQI6XSLkzEENWl6MfdcekOppjjcnm8Bn5IKCoSg4OFiXYd0pwFaYBwcB+uggrTNwZL6rnpBEGA7XgzsggQXwSlULmCCTrLXU9ZaxEErlTUnS9DoDAARAQXkyyo+c3czdtOPO7NXtyCQgujsP9gDrO4cDsMIcAaXN7hadpWmAgFQWJM0BGtNscBhe5NF6M9em-RxfzNAC5CAxNwKNKAoOAGCGiwrZHG0TQgA) with the new decorators that @rbuckton has been working on. I want to make a property decorator work with both accessors and setters, taking advantage of control flow analysis to return the appropriate value without casting.