-
Notifications
You must be signed in to change notification settings - Fork 12.8k
Bail on 0- and 1-length lists in removeSubtypes
to avoid spurious circularity problems
#46981
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
removeSubtypes
to avoid spurious circularity problemsremoveSubtypes
to avoid spurious circularity problems
This code has a type circularity that previously went undetected. Adding an `as Wizard` assertion here removes the circularity. See microsoft/TypeScript#46939 / microsoft/TypeScript#46981
@typescript-bot perf test this |
Heya @RyanCavanaugh, I've started to run the perf test suite on this PR at dd91ab7. You can monitor the build here. Update: The results are in! |
@RyanCavanaugh Here they are:Comparison Report - main..46981
System
Hosts
Scenarios
Developer Information: |
I'm want to merge this, because I think the early bail is fine to have regardless of anything else, however I think there's another underlying issue that probably needs fixing, so it'd be nice if we had a tweaked example that still triggered an issue and an issue to track fixing it. Likely something like type Box = {
content?: Foo | Box
};
declare const b: Box;
class Foo {
get foo() {
return {
content: this as Foo | Box,
...b
};
}
} will continue to trigger a new-ish circularity error. |
Creates a reasonable workaround for #46939
Another example for illustration:
When resolving the type of
Foo#foo
, we need to compute the type of the object literal in the return position. This has two parts: thecontent
from thecontent:
property (typeFoo
), and thecontent
property from typeBox
(which isFoo | missing
).We want the type of
content
here to be subtype-reduced when creating the union of the two possible constituents,Foo
andFoo
. That list gets deduped ingetUnionType
to just[Foo]
, then passed toremoveSubTypes
, which computes this value ahead of thewhile
loop below it which in reality runs zero iterations:That call to
resolveStructuredTypeMembers
attempts to resolve the type ofFoo#foo
, triggering a circularity even though none actually exists.Instead we can just bail out earlier in the function, saving time (I hope?) and avoiding this computation until later when doing so won't introduce a circularity.