Repository: TypeScript
Issue: Type inference when combining inheritance, optional properties and union type
Labels: Bug,Domain: Control Flow

<!-- 🚨 STOP 🚨 𝗦𝗧𝗢𝗣 🚨 𝑺𝑻𝑶𝑷 🚨

Half of all issues filed here are duplicates, answered in the FAQ, or not appropriate for the bug tracker. Even if you think you've found a *bug*, please read the FAQ first, especially the Common "Bugs" That Aren't Bugs section!

Please help us by doing the following steps before logging an issue:
  * Search: https://github.com/Microsoft/TypeScript/search?type=Issues
  * Read the FAQ: https://github.com/Microsoft/TypeScript/wiki/FAQ

Please fill in the *entire* template below.
-->

<!-- Please try to reproduce the issue with `typescript@next`. It may have already been fixed. -->
**TypeScript Version:**  3.3.0-dev.20181130

<!-- Search terms you tried before logging this (so others can find this issue more easily) -->
type inference
type inference inheritance
type inference inheritance optional
type inference inheritance optional property
type inference inheritance optional union type
type inference inheritance optional property union type

**Code** 
```ts
export class ModelBase {
  modelBaseProp: boolean;

  constructor() {
  }
}

export class Model1 extends ModelBase {
  model1Prop?: number;

  constructor() {
    super();
  }
}

export class Model2 extends ModelBase {
  model2Prop?: string;

  constructor() {
    super();
  }
}

export class Test {
  test: Model1 | Model2;
  constructor() {
    this.test = new Model1();
    this.test.model1Prop = 1;

    this.test = new Model2();
    this.test.model2Prop = 'test';
  }
}
```

**Expected behavior:**
No compilation errors.

**Actual behavior:**
`error TS2339: Property 'model1Prop' does not exist on type 'Model1 | Model2'.
  Property 'model1Prop' does not exist on type 'Model2'`
and
`error TS2339: Property 'model2Prop' does not exist on type 'Model1 | Model2'.
  Property 'model2Prop' does not exist on type 'Model1'.`

**Playground Link:** [link](http://www.typescriptlang.org/play/#src=export%20class%20ModelBase%20%7B%0D%0A%20%20modelBaseProp%3F%3A%20boolean%3B%0D%0A%0D%0A%20%20constructor()%20%7B%0D%0A%20%20%7D%0D%0A%7D%0D%0A%0D%0Aexport%20class%20Model1%20extends%20ModelBase%20%7B%0D%0A%20%20model1Prop%3F%3A%20number%3B%0D%0A%0D%0A%20%20constructor()%20%7B%0D%0A%20%20%20%20super()%3B%0D%0A%20%20%7D%0D%0A%7D%0D%0A%0D%0Aexport%20class%20Model2%20extends%20ModelBase%20%7B%0D%0A%20%20model2Prop%3F%3A%20string%3B%0D%0A%0D%0A%20%20constructor()%20%7B%0D%0A%20%20%20%20super()%3B%0D%0A%20%20%7D%0D%0A%7D%0D%0A%0D%0Aexport%20class%20Test%20%7B%0D%0A%20%20test%3A%20Model1%20%7C%20Model2%3B%0D%0A%20%20constructor()%20%7B%0D%0A%20%20%20%20this.test%20%3D%20new%20Model1()%3B%0D%0A%20%20%20%20this.test.model1Prop%20%3D%201%3B%0D%0A%0D%0A%20%20%20%20this.test%20%3D%20new%20Model2()%3B%0D%0A%20%20%20%20this.test.model2Prop%20%3D%20'test'%3B%0D%0A%20%20%7D%0D%0A%7D)

**Additional info** Making the properties in the derived classes non-optional works as expected. Note that the following is working properly: [Playground link](http://www.typescriptlang.org/play/#src=export%20class%20Model1%20%7B%0D%0A%20%20model1Prop%3F%3A%20number%3B%0D%0A%0D%0A%20%20constructor()%20%7B%0D%0A%20%20%7D%0D%0A%7D%0D%0A%0D%0Aexport%20class%20Model2%20%7B%0D%0A%20%20model2Prop%3F%3A%20string%3B%0D%0A%0D%0A%20%20constructor()%20%7B%0D%0A%20%20%7D%0D%0A%7D%0D%0A%0D%0Aexport%20class%20Test%20%7B%0D%0A%20%20test%3A%20Model1%20%7C%20Model2%3B%0D%0A%20%20constructor()%20%7B%0D%0A%20%20%20%20this.test%20%3D%20new%20Model1()%3B%0D%0A%20%20%20%20this.test.model1Prop%20%3D%201%3B%0D%0A%0D%0A%20%20%20%20this.test%20%3D%20new%20Model2()%3B%0D%0A%20%20%20%20this.test.model2Prop%20%3D%20'test'%3B%0D%0A%20%20%7D%0D%0A%7D)
```ts
export class Model1 {
  model1Prop?: number;

  constructor() {
  }
}

export class Model2 {
  model2Prop?: string;

  constructor() {
  }
}

export class Test {
  test: Model1 | Model2;
  constructor() {
    this.test = new Model1();
    this.test.model1Prop = 1;

    this.test = new Model2();
    this.test.model2Prop = 'test';
  }
}
```