Skip to content

Excess property checking only checks top level when target type is a union #21187

Closed
@DHainzl

Description

@DHainzl

When using Discriminated Unions with properties with interfaces as types, TS does not seem to infer the discrimination correctly when defining a variable of that type. See the following example:

TypeScript Version: 2.7.0-dev.201xxxxx

Code

interface FooA {
    kind: 'A';
    settings: FooASettings;
}
interface FooB {
    kind: 'B';
    someB: string;
    settings: FooBSettings;
}
interface FooASettings {
    foo: string;
}
interface FooBSettings {
    bar: string;
}
type Foo = FooA | FooB;

const x: Foo = {
    kind: 'A',
//  someB: 'XX',            // WORKS Would error as expected as `FooA` does not contain `someB`
    settings: {             // FAILS Expected: `FooASettings`, Got: `FooASettings | FooBSettings`
        foo: 'foo',
        bar: 'bar',         // FAILS Expected: Failure
    }
}

if (x.kind === 'A') {
    x.settings;             // WORKS `FooASettings`, as expected
}

Expected behavior:

x.settings should be FooASettings in the type, and not deducted as FooASettings | FooBSettings. It works correctly when using the variable, but not when defining it.

Related:
I was unable to find any directly related issue for this case, the only thing I found was #12745 (comment) which might has the same root issue.

Metadata

Metadata

Assignees

No one assigned

    Labels

    BugA bug in TypeScriptFixedA PR has been merged for this issue

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions