Skip to content

Unable to discriminate union type because of "Property does not exist" #28138

Closed
@lemoinem

Description

@lemoinem

TypeScript Version: [email protected]

Search Terms: union narrowing discriminate missing property field

Code

class Foo
{
    private foo: string;
}

class Bar
{
    private bar: number;
}

function fn(baz: { foo: Foo; bar: string; } | { foo: Bar; })
{
    if (typeof baz.bar != 'undefined')
    {
        testFoo(baz.foo);
    }
}

function testFoo(foo: Foo)
{
}

Expected behavior:
No Error. I can call testFoo(baz.foo) since the union type is properly narrowed.

Actual behavior:
Property 'bar' does not exist on type 'Baz'.

Argument of type 'Foo | Bar' is not assignable to parameter of type 'Foo'.
Type 'Bar' is not assignable to type 'Foo'.
Property 'foo' is missing in type 'Bar'.

Playground Link: https://www.typescriptlang.org/play/index.html#src=class%20Foo%0D%0A%7B%0D%0A%20%20%20%20private%20foo%3A%20string%3B%0D%0A%7D%0D%0A%0D%0Aclass%20Bar%0D%0A%7B%0D%0A%20%20%20%20private%20bar%3A%20number%3B%0D%0A%7D%0D%0A%0D%0Afunction%20fn(baz%3A%20%7B%20foo%3A%20Foo%3B%20bar%3A%20string%3B%20%7D%20%7C%20%7B%20foo%3A%20Bar%3B%20%7D)%0D%0A%7B%0D%0A%20%20%20%20if%20(typeof%20baz.bar%20!%3D%20'undefined')%0D%0A%20%20%20%20%7B%0D%0A%20%20%20%20%20%20%20%20testFoo(baz.foo)%3B%0D%0A%20%20%20%20%7D%0D%0A%7D%0D%0A%0D%0Afunction%20testFoo(foo%3A%20Foo)%0D%0A%7B%0D%0A%7D

Related Issues: I've looked around but found none.

Although, in general, I do understand this should not work, I think it would help greatly if we had a way to discriminate on properties that are only in some of the members of a union.

One of the solutions could be to type properties, that are missing in some of the union members as prop?: void, or prop?: never, or prop?: undefined, or whatever makes sense in the type system.

Metadata

Metadata

Assignees

No one assigned

    Labels

    QuestionAn issue which isn't directly actionable in code

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions