-
Notifications
You must be signed in to change notification settings - Fork 12.8k
Ensure common supertype retains nullability in inference #49981
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
Conversation
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
Well, I narrowed this down to operate strictly on only unions and direct types, so it shouldn't have that build problem anymore (and I encoded it as a test). |
@typescript-bot test this |
Heya @jakebailey, I've started to run the extended test suite on this PR at a817435. You can monitor the build here. |
Heya @jakebailey, I've started to run the diff-based user code test suite on this PR at a817435. You can monitor the build here. Update: The results are in! |
Heya @jakebailey, I've started to run the tarball bundle task on this PR at a817435. You can monitor the build here. |
Hey @jakebailey, I've packed this into an installable tgz. You can install it for testing by referencing it in your
and then running There is also a playground for this build and an npm module you can use via |
Heya @jakebailey, I've run the RWC suite on this PR - assuming you're on the TS core team, you can view the resulting diff here. |
@jakebailey |
Demo as of this current commit: Playground Link |
RE: the RWC tests, I think there might be one error in there that's real, but I'm having trouble understanding what's going on there because it looks like a bunch of unrelated things are showing up in the diff that shouldn't be there if the diff was running on the same version of the test codebases. The error sort of implies that |
@typescript-bot perf test this faster |
Heya @jakebailey, I've started to run the abridged perf test suite on this PR at a817435. You can monitor the build here. Update: The results are in! |
@jakebailey Here they are:Comparison Report - main..49981
System
Hosts
Scenarios
Developer Information: |
function someHas(type: Type, flags: TypeFlags): boolean { | ||
return someType(type, t => !!(t.flags & flags)); |
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.
This feels common enough that I would rather us lift it up to someTypeHasFlags
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 can do that, yeah, though I think most places just entirely inline it, so I could just do that too.
#50021 is a more complete fix than mine now, so, closing. |
Fixes #49938
Demo: Playground Link
The common supertype of a bunch of inference candidates should include
null
andundefined
of those candidates can benull
orundefined
.#49119 and #49330 changed the way this information was stored and propagated. It turns out that the old code only worked because of a fluke related to those flags. In v4.7.4, given the types in the playground link above:
B
andD | undefined
. We declare that these are both "primary types" because neither are exactlynull
orundefined
.B
as it's the leftmost option.null
orundefined
, but using a function that is recursive, so we findD | undefined
, when the intent was to just find exactlynull
orundefined
.B
to getB | D | undefined
, which reduces toD | undefined
, and we get the supertype that everyone had expected all along, even though that's maybe not what the code was written to do!Instead, we can just compare the candidates without
null
orundefined
, then addnull
orundefined
back on again if the supertype needs it; this means that the cases we supported in 4.7.4 work (and now work the same regardless of argument order).