-
Notifications
You must be signed in to change notification settings - Fork 12.6k
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
Newly introduced type narrowing via discriminators on .filter does not work in this case #59654
Comments
And interestingly enough, faking a filter with flatMap() does work.
|
To infer a type predicate TypeScript has to prove both that the narrowed-down type is declare const x: C | D;
if (x.discriminator === "C") {
x; // C
} else {
x; // D (aka C is 100% eliminated from reaching this branch)
} In this situation, this isn't something that can be proved. If you inspect the code above u might see that TLDR: type predicates have to be exhaustive, this type predicate candidate isn't. |
Thanks a lot @Andarist for trying to explain this to me. But I still don't get it actually. Can you explain it like I'm 5, or simplify the explanation even more? What I don't understand is this: If I directly check on discriminator being "C" in a filter, why would that inference be any different than if I just did it in an if-statement? In other words, if I check that the discriminator is "C", wouldn't that be known for sure, like in your example? And then, how does doing that in a |
Take a look at this TS playground. The else branch still contains
You might find this comment helpful. Type predicates must prove the function can't return |
Aha, I think I understand now. So it's because they both have "undefined" in common, and therefore none of them can be ruled out? |
But this should be fixable, right? Because in the filter function, I am not using the "else" case at all. I'm filtering only on the exact matches. |
Not quite. It doesn't matter that It happens solely because it's possible to get const predicateCandidate = (x: C | D) => x.discriminator === "C"
const c: C = { discriminator: undefined }
predicateCandidate(c) // false
This would be a feature request to add something new so that |
Also see #15048 for discussion of the typeguards separately from the |
This issue has been marked as "Duplicate" and has seen no recent activity. It has been automatically closed for house-keeping purposes. |
π Search Terms
"type narrowing", "discriminator"
π Version & Regression Information
.filter
operations.β― Playground Link
https://www.typescriptlang.org/play/?#code/C4TwDgpgBAglC8UDeAoKUAmBLAzgYwCcsBbLAOwENgB7AgLigCIZGUBfFFUSKAIQWRpMuQiXJVaDRr1Ycu4aAGEBqdNnxFSlGgQD8UxbM7doAERVD1orRL1TTRznmpkcwKBQIEKIAWQgA7rBePgA8cAA+fAB8ABQAlADcKM6u7gBmWAA2wBAEEBgwIb6Int4gAHSZOXmxAB4I0VB1FVaa4joI8IjMjPEoAPQDABZ5EAA0UNW5+YXFULhQzl4QeMBZvtTpUCZMMADaALqsKS5uUNTAowRF5X6BweWhylGmcUmnaVPZMwUA8lc8rcfAJLtdgZVprUGvAmi02mJtLQuj1DB8htcJt8arMAeD5otyMt8msNhdtrtGLFFBFTPEjowoAAjACu7hww2oLKyGGZ0EYigZgwGWHcLjJwwoYEgrimyOoYGAWBcFCywg0iNsUDABAVeSVEBwQA
π» Code
π Actual behavior
In the example,
filteredOtherArray
is incorrectly of type "(C|D)[]"π Expected behavior
In the example,
filteredOtherArray
should be of typeC[]
.Additional information about the issue
No response
The text was updated successfully, but these errors were encountered: