Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Type predicate not inferred for discriminated union? #57947

Closed
krryan opened this issue Mar 26, 2024 · 0 comments · Fixed by #57952
Closed

Type predicate not inferred for discriminated union? #57947

krryan opened this issue Mar 26, 2024 · 0 comments · Fixed by #57952
Labels
Bug A bug in TypeScript
Milestone

Comments

@krryan
Copy link

krryan commented Mar 26, 2024

🔎 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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug A bug in TypeScript
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants