<!-- BUGS: Please use this template. --> <!-- QUESTIONS: This is not a general support forum! Ask Qs at http://stackoverflow.com/questions/tagged/typescript --> <!-- SUGGESTIONS: See https://github.com/Microsoft/TypeScript-wiki/blob/master/Writing-Good-Design-Proposals.md --> **TypeScript Version:** nightly (2.0.0-dev.201xxxxx) **Code** ``` ts type ToString = { toString(): string; } type BoxedValue = { kind: 'int', num: number } | { kind: 'string', str: string } type IntersectionFail = BoxedValue & ToString type IntersectionInline = { kind: 'int', num: number } & ToString | { kind: 'string', str: string } & ToString function getValueAsString(value: IntersectionFail): string { if (value.kind === 'int') { // Property 'num' does not exist on type '({ kind: "int"; num: number; } | { kind: "string"; str: string; }) & { toString(): string; }'. return '' + value.num; } // Property 'str' does not exist on type '({ kind: "int"; num: number; } | { kind: "string"; str: string; }) & { toString(): string; }'. return value.str; } ``` If a discriminated union is enhanced via intersection, type narrowing based on the discrimination field starts to fail. This behaviour is not exhibited if a new discriminated union is created with the intersection being inlined into each of the respective options. The function `getValueAsString(value: IntersectionFail): string` fails to compile, while `getValueAsString(value: IntersectionInline): string` compiles just fine. Unfortunately, it is `IntersectionFail` that is the result of natural program evolution.