-
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
Insufficient type narrowing of object with a union property #33467
Comments
I will always be against having this narrowing implemented because of, //Assume this works
const hasFoo: HasFoo = maybeFoo;
maybeFoo.foo = null;
console.log(hasFoo.foo)//not a string |
Your second example (alleged workaround of Issue 1) is saying a very different thing from the first example. //In the second example
const hasFoo: HasFoo = maybeFoo;
maybeFoo.foo = null; //Error, cannot assign null to string |
type MaybeFoo = NoFoo | HasFoo; And type MaybeFoo = Base & { foo: string | null }; Are not the same type and should not be treated the same The narrowing you desire hasn't been implemented because it isn't safe. Not because of performance reasons, as pointed out in the other issues. |
Great point. So you're saying they're not equivalent because you can reassign foo. Would the types be equivalent if all the properties were readonly? Sprinkling readonly everywhere doesn't make any of the errors go away. |
Ah, I just read the discussion on #33205 where you covered why readonly doesn't change anything (because it's not absolute). I agree now that Issue 1 is working as intended. What do you think about Issue 2 though? |
For issue 2 (this playground), it makes sense that the assignment should be sound. I'm not sure if it'll be marked as a duplicate of something else or "design limitation", though. @jack-williams What do you think about that issue 2 thing? The other issues don't talk about fresh object literals on the RHS of the assignment |
I’m pretty sure issue 2 is a bug as per my first comment. If you remove the intersections and just use a union of object literals it works |
Ah. It wasn't obvious to me the issues were indeed related because I was stuck on the fresh object literal part. I didn't try to remove the intersection =x |
This issue has been marked as a 'Duplicate' and has seen no recent activity. It has been automatically closed for house-keeping purposes. |
TypeScript Version: [email protected] (typescript@next)
Search Terms: union property type narrowing
Note: this is two bugs in one but they look related. "Issue 2" might actually be more damning.
Issue 1
Code
Expected behavior:
Should compile because the conditional should have narrowed the MaybeFoo to a HasFoo.
Actual behavior:
Playground Link: click
Related Issues: had a quick search but couldn't anything
Workaround
This code is exactly the same, but compiles
Playground Link click
Issue 2
Now let's try using the same type definitions as maybe2.ts, but try creating a MaybeFoo:
Expected behavior:
Should compile.
Actual behavior:
Playground Link click
Issue 2 Workaround
Changing back to the original type definitions fixes it:
Playground Link: click
The text was updated successfully, but these errors were encountered: