Repository: TypeScript
Issue: Cant infer type of parent based on member of child
Labels: Suggestion,In Discussion

<!-- 🚨 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.4.5

<!-- Search terms you tried before logging this (so others can find this issue more easily) -->
**Search Terms:**
- infer parent based on child 
- type inference in if statement 
- conditional generic type infer

**Code**

```ts
const enum ChildType {
    A,
    B,
    C
}

interface ChildrenMap {
    [ChildType.A]: { value: 10 },
    [ChildType.B]: { value: string },
    [ChildType.C]: { value: boolean, test?: boolean }
};

// Create a "Child", that has a type and
// other members based on what type it is
type Child<T extends ChildType> = { type: T } & ChildrenMap[T];

interface ParentMap {
    [ChildType.A]: { color: 'red' },
    [ChildType.B]: { color: 'blue' },
    [ChildType.C]: { color: 'green' }
}

// Create a "Parent", that has a "Child", which
// has a type, which decides what members the 
// parent should have
type Parent<T extends Child<any>> =
    T extends Child<infer R>
    ? R extends ChildType ? ParentMap[R] & { child: Child<R> }
    : never 
    : never;

// More of the same stuff!
interface GrandParent<T extends Parent<Child<any>>> {
    parent: T extends Parent<Child<infer R>>
    ? R extends ChildType ? Parent<Child<R>>
    : never
    : never; 
}

// It all works as expected at this point
let A: Parent<Child<ChildType.A>>;
let red: typeof A['color'] = 'red';
let justRed: typeof A['color'] = 'blue'; // error!

// Same sorta thing as ^
let B: Parent<Child<ChildType.B>>;
let C: Parent<Child<ChildType.C>>;

function testParent<T extends Parent<any>>(parent: T) {
    if (parent.child.type === ChildType.A) {
        parent.child.value; // equals 10!
        parent.color; // red | green | blue, but should only be red
    }
}

function testGrandParent<T extends GrandParent<any>>(grandParent: T) {
    if (grandParent.parent.child.type === ChildType.B) {
        grandParent.parent.child.value; // string, yay!
        grandParent.parent.color; // red | green | blue, but should only be blue
    }
}
```

**Expected behavior:**
As the type of "Child" is being set using the same conditional type as the parent, the parent type should also get the appropriate type for "color".
In the case of `testParent`, the statement `parent.type === ChildType.A` correctly infers the value of `value` (in the case of that example 10). This should also happen for the top level member "color" as well (in the case of that example, `color` should be set to `"red"`).

**Actual behavior:**
`parent.child.type` and `parent.child.value`, correctly coerce the appropriate type. However `color` is incorrect `"red" | "blue" | "green"` instead of one of the three. 

**Playground Link:** <!-- A link to a TypeScript Playground "Share" link which demonstrates this behavior -->

[link to the playground](https://www.typescriptlang.org/play/#src=const%20enum%20ChildType%20%7B%0D%0A%20%20%20%20A%2C%0D%0A%20%20%20%20B%2C%0D%0A%20%20%20%20C%0D%0A%7D%0D%0A%0D%0Ainterface%20ChildrenMap%20%7B%0D%0A%20%20%20%20%5BChildType.A%5D%3A%20%7B%20value%3A%2010%20%7D%2C%0D%0A%20%20%20%20%5BChildType.B%5D%3A%20%7B%20value%3A%20string%20%7D%2C%0D%0A%20%20%20%20%5BChildType.C%5D%3A%20%7B%20value%3A%20boolean%2C%20test%3F%3A%20boolean%20%7D%0D%0A%7D%3B%0D%0A%0D%0A%2F%2F%20Create%20a%20%22Child%22%2C%20that%20has%20a%20type%20and%0D%0A%2F%2F%20other%20members%20based%20on%20what%20type%20it%20is%0D%0Atype%20Child%3CT%20extends%20ChildType%3E%20%3D%20%7B%20type%3A%20T%20%7D%20%26%20ChildrenMap%5BT%5D%3B%0D%0A%0D%0Ainterface%20ParentMap%20%7B%0D%0A%20%20%20%20%5BChildType.A%5D%3A%20%7B%20color%3A%20'red'%20%7D%2C%0D%0A%20%20%20%20%5BChildType.B%5D%3A%20%7B%20color%3A%20'blue'%20%7D%2C%0D%0A%20%20%20%20%5BChildType.C%5D%3A%20%7B%20color%3A%20'green'%20%7D%0D%0A%7D%0D%0A%0D%0A%2F%2F%20Create%20a%20%22Parent%22%2C%20that%20has%20a%20%22Child%22%2C%20which%0D%0A%2F%2F%20has%20a%20type%2C%20which%20decides%20what%20members%20the%20%0D%0A%2F%2F%20parent%20should%20have%0D%0Atype%20Parent%3CT%20extends%20Child%3Cany%3E%3E%20%3D%0D%0A%20%20%20%20T%20extends%20Child%3Cinfer%20R%3E%0D%0A%20%20%20%20%3F%20R%20extends%20ChildType%20%3F%20ParentMap%5BR%5D%20%26%20%7B%20child%3A%20Child%3CR%3E%20%7D%0D%0A%20%20%20%20%3A%20never%20%0D%0A%20%20%20%20%3A%20never%3B%0D%0A%0D%0A%2F%2F%20More%20of%20the%20same%20stuff!%0D%0Ainterface%20GrandParent%3CT%20extends%20Parent%3CChild%3Cany%3E%3E%3E%20%7B%0D%0A%20%20%20%20parent%3A%20T%20extends%20Parent%3CChild%3Cinfer%20R%3E%3E%0D%0A%20%20%20%20%3F%20R%20extends%20ChildType%20%3F%20Parent%3CChild%3CR%3E%3E%0D%0A%20%20%20%20%3A%20never%0D%0A%20%20%20%20%3A%20never%3B%20%0D%0A%7D%0D%0A%0D%0A%2F%2F%20It%0D%0Alet%20A%3A%20Parent%3CChild%3CChildType.A%3E%3E%3B%0D%0Alet%20red%3A%20typeof%20A%5B'color'%5D%20%3D%20'red'%3B%0D%0Alet%20justRed%3A%20typeof%20A%5B'color'%5D%20%3D%20'blue'%3B%20%2F%2F%20error!%0D%0A%0D%0A%2F%2F%20Same%20as%20%5E%0D%0Alet%20B%3A%20Parent%3CChild%3CChildType.B%3E%3E%3B%0D%0Alet%20C%3A%20Parent%3CChild%3CChildType.C%3E%3E%3B%0D%0A%0D%0Afunction%20testParent%3CT%20extends%20Parent%3Cany%3E%3E(parent%3A%20T)%20%7B%0D%0A%20%20%20%20if%20(parent.child.type%20%3D%3D%3D%20ChildType.A)%20%7B%0D%0A%20%20%20%20%20%20%20%20parent.child.value%3B%20%2F%2F%20equals%2010!%0D%0A%20%20%20%20%20%20%20%20parent.color%3B%20%2F%2F%20red%20%7C%20green%20%7C%20blue%2C%20but%20should%20only%20be%20red%0D%0A%20%20%20%20%7D%0D%0A%7D%0D%0A%0D%0Afunction%20testGrandParent%3CT%20extends%20GrandParent%3Cany%3E%3E(grandParent%3A%20T)%20%7B%0D%0A%20%20%20%20if%20(grandParent.parent.child.type%20%3D%3D%3D%20ChildType.B)%20%7B%0D%0A%20%20%20%20%20%20%20%20grandParent.parent.child.value%3B%20%2F%2F%20string%2C%20yay!%0D%0A%20%20%20%20%20%20%20%20grandParent.parent.color%3B%20%2F%2F%20red%20%7C%20green%20%7C%20blue%2C%20but%20should%20only%20be%20blue%0D%0A%20%20%20%20%7D%0D%0A%7D)

**Related Issues:** <!-- Did you find other bugs that looked similar? -->