-
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
Fix empty object falsiness #27157
Fix empty object falsiness #27157
Conversation
@@ -14169,9 +14175,11 @@ namespace ts { | |||
(type === falseType || type === regularFalseType) ? TypeFacts.FalseFacts : TypeFacts.TrueFacts; | |||
} | |||
if (flags & TypeFlags.Object) { | |||
return isFunctionObjectType(<ObjectType>type) ? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The empty object type is a red herring. The issue also exists for other structural types which have falsy types structurally assignable to them, like { toString(): string; }
, { toFixed(): string; }
, or { readonly length: number }
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right, in an ideal world we'd check whether ""
, 0
, or false
is assignable to the type in question, but I'm concerned about the performance impact.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it shouldn't be too bad, given that we'll be doing the check only once for all string-subtypes, number-subtypes, etc (since for structural comparison we'll be comparing the apparent type) vs each input type, then caching the relation comparison result for every other time we check it. And the check itself should (in the common case of failure) bail out really early when the property keys don't sufficiently overlap.
So what's the impact here? We discussed offline and felt that this might be too painful for a lot of practical uses. |
@DanielRosenwasser you just ask @typescript-bot test this to find out |
Heya @weswigham, I've started to run the extended test suite on this PR at 17080eb. You can monitor the build here. It should now contribute to this PR's status checks. |
@DanielRosenwasser I just ran the RWC tests locally. No breaks as a result of this. |
The RWC baseline change shown by the bot is actually a desired change, so no breaks. |
We currently consider
{}
and unconstrained type parameters to never be falsy in--strictNullChecks
mode. This is wrong as{}
or an unconstrained type parameter might represent a string, number, or boolean value and thus one of the falsy values"" | 0 | false
. This PR corrects our assumptions.This PR furthermore fixes an issue with type parameters of the form
T extends { [K in keyof T]: string }
. For such a type parameter,keyof T
will have itself as its constraint and this circularity caused every type to be considered related tokeyof T
.Fixes #18196.
Fixes #27181.