Repository: TypeScript
Issue: Multiple sets of mutually exclusives properties lead to wrong compiler error
Labels: Suggestion,Help Wanted,Experience Enhancement

# Bug Report

### 🔎 Search Terms

type union interface mutually exclusive property never

### 🕗 Version & Regression Information

I stumble on it today.
Happen in the nightly.
Happen from ES3 to ESNext on the playground.

- This is the behavior in every version I tried, and I reviewed the FAQ for entries about a bug with properties of type never.

### ⏯ Playground Link

[Playground link with relevant code](https://www.typescriptlang.org/play?noUncheckedIndexedAccess=true&target=99&jsx=0&suppressImplicitAnyIndexErrors=true&exactOptionalPropertyTypes=true&ts=4.7.0-dev.20220302#code/JYOwLgpgTgZghgYwgAgArQM4HsQCgDeuyxyA1qACYBcyAROlNiLQNxEkhwC2ENGYUUAHM2AX1y5QkWIhQBhLFwAOcEAE8C7YuRDU6C5arWstyTjz4DhYiVOjwkyAPowoihk00lkr95hw0Hjhs3r5cBirqAPw0IBAAbtA2kuD2ss5hEUZeJGFBIDFmCUmmmYqRajRZ6sl2Mo5OYFj5OcRN+YH+ICEkTdVqhXGJULWp9SiNWP2tyO1dg8Ujpn3lRlWrNbjiKdIOKABKcADuALIQGBhwQhAzYMA8-NxKsQCuXABGJd53YAA2vMh+IIQCJTAgcJBwJZgaDtmA1EoUGcLlcUABeZAAClMh1O50u11MADIsS43Fx8sgAD4Zcn9ACUxNJc0YOGpzhWhnUjPpbFw4JA-GQJwAogBlMUAQQA4iKaMiCejkIRvvdzmAnjQAIwAVgA7HqABwAZgAbIaAAxWq0AGmWwD+ANoIoAHk9-rQ7d4BZCwDRaAAhF5CZAQN3KD1e3LkjrK0zeHR6ehdT3xjjcJ20UyiKNtZpdGgq7wkRP+-Kp4vpix0LPeHPLKYbSpxyvaSj+-oV1vmTPZu2iPlAA)

### 💻 Code

```ts
interface Person
{
    kind: "Person";
    name: string;
}

interface Company
{
    kind: "Company";
    name: string;
}

// Fragments
interface _fromPerson
{
    fromPerson: Person;
    fromCompany?: never;
}

interface _fromCompany
{
    fromPerson?: never;
    fromCompany: Company;
}

interface _toPerson
{
    toPerson: Person;
    toCompany?: never;
}

interface _toCompany
{
    toPerson?: never;
    toCompany: Company;
}

interface RawMessage
{
    timestamp: number;
    title: string;
    content: string;
}

// Combined type
type Message = (
    RawMessage
    & (_fromPerson | _fromCompany)
    & (_toPerson | _toCompany)
);

const MESSAGE: Message = {
    timestamp: 1577836800000,
    title: "Bug",
    content: "This is an example",
    fromPerson: {
        kind: "Person",
        name: "Alice"
    },
    toPerson: {
        kind: "Person",
        name: "Bob"
    },
    toCompany: {
        kind: "Company",
        name: "ACME"
    },
};
```

### 🙁 Actual behavior

`toPerson` and `toCompany` are mutually exclusive, but the compiler report as error that property `fromCompany` is missing while `fromPerson` is already there and mutually exclusive with `fromCompany`.

```
(ts2322)
Type '{ ... }' is not assignable to type 'Message'.
  Type '{ ... }' is not assignable to type 'RawMessage & _fromCompany & _toCompany'.
    Property 'fromCompany' is missing in type '{ ... }' but required in type '_fromCompany'.
```

If you only have 1 set of mutually exclusive interfaces, you get a correct error :
```
(ts2322)
Type '{ ... }' is not assignable to type 'Message'.
  Type '{ ... }' is not assignable to type 'RawMessage & _toCompany'.
    Type '{ ... }' is not assignable to type '_toCompany'.
      Types of property 'toPerson' are incompatible.
        Type '{ kind: "Person"; name: string; }' is not assignable to type 'never'.
```

### 🙂 Expected behavior

The compiler do not mention `fromCompany`, but mention `toPerson` and `toCompany` being mutually exclusive.
```
(ts2322)
Type '{ ... }' is not assignable to type 'Message'.
  Type '{ ... }' is not assignable to type 'RawMessage & _toCompany'.
    Type '{ ... }' is not assignable to type '_toCompany'.
      Types of property 'toPerson' are incompatible.
        Type '{ kind: "Person"; name: string; }' is not assignable to type 'never'.
```