Skip to content

Type predicate not inferred for discriminated union? #57947

@krryan

Description

@krryan

🔎 Search Terms

"type predicate", "infer", "discriminated union"

🕗 Version & Regression Information

tested on 5.5.0-dev20240318, 5.5.0-dev20240326

⏯ Playground Link

https://www.typescriptlang.org/play?ts=5.5.0-dev.20240326#code/CYUwxgNghgTiAEYD2A7AzgF3gMyUgRrAFzwDe8GAngA4gkDkuS9A3DniSgK4C2+IMeAF94AHzIUadePUIxW8OSUwwAligDmwlgChV2eAAomcgHRVa8ALw2ZTegEoyO+K-YFYpprqE6dydCxqOGBrI2x8EgsQJAMTWCcrAD4cfHMpa1tGPFY9A0NgkGBjPDkHJ1IXN3iYLzwfP1BIWAQAzHc5NBJDaNiOhIBtAF1dGrQvVQgMAWN8axSI9MsbKzsch1MeKGpDQ3ImYUSFvAcWIA

💻 Code

declare const foobar: { type: 'foo'; foo: number } | { type: 'bar'; bar: string };
if (foobar.type === 'foo') {
    foobar.foo;
}

const pred = (fb: typeof foobar) => fb.type === 'foo';
if (pred(foobar)) {
    foobar.foo;
}

declare const foobars: (typeof foobar)[];
foobars.filter(fb => fb.type === 'foo').map(({ foo }) => foo);

🙁 Actual behavior

Line 6’s pred and the anonymous function passed to the foobars.filter method on line 12 are each inferred as (fb: typeof foobar) => boolean, leading to the errors on lines 8 and 12. Both errors are, unsurprisingly,

Property 'foo' does not exist on type '{ type: "foo"; foo: number; } | { type: "bar"; bar: string; }'.

🙂 Expected behavior

The predicates on lines 6 and 12 should be inferred as (fb: typeof foobar) => fb is { type: "foo"; foo: number; }, so they narrow foobar the same way the inline condition on line 2 does.

Additional information about the issue

This is a very-new feature, and from reading the PR it’s clear that it is (intentionally) not everything it could be yet, but as far as I can tell based on #57465 (and the fact that it closed my prior suggestion #50734), these predicates should be inferred correctly here. If I misunderstand, then I suppose this should have been a feature request rather than a bug report, but the point remains that this is a massive limitation in this feature, since the overwhelming majority of type predicates our project deals with are discriminated unions of this sort.

Metadata

Metadata

Assignees

No one assigned

    Labels

    BugA bug in TypeScript

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions