-
Notifications
You must be signed in to change notification settings - Fork 12.8k
Extend isEmptyAnonymousObjectType
with support for non-generic mapped types
#56974
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
base: main
Are you sure you want to change the base?
Conversation
@@ -20849,7 +20849,11 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { | |||
} | |||
|
|||
function isEmptyAnonymousObjectType(type: 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.
Note that this is different from isEmptyObjectType
and none of those reuse the other. Perhaps with this change, some sharing could be introduced. I tried that at first and a lot of tests failed - but I didn't bother digging into this right now.
I don't really know what's the intended use case of both. Some code comments here would be highly appreciated. I could add the. However, I'd need first to learn from the team about the different goals of those two.
import { B, C, D } from './types2'; | ||
|
||
export class C implements Base { | ||
a: Readonly<A> & { kind: 'a'; }; |
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 is a somewhat unfortunate change. However, it matches the behavior of plain A
that is {}
. In such a case, A
doesn't appear in the output after the refactoring. Maybe that's an issue worth raising? The intention of the user could have been to reuse types from the interface quite literally - so when they start implementing A
's members the C
class automatically "receives" them.
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 agree that it might be unfortunate, but I think this change is ok. If we want to have a mechanism for preserving those kinds of intersections in refactorings and codefixes, we need it to also work for A & { kind: ... }
.
verify.completions({ marker: "3", exact: [] }); | ||
verify.completions({ marker: "4", exact: [] }); | ||
verify.completions({ marker: "5", includes: ["a", "b", "c"] }); | ||
verify.completions({ marker: "5", exact: [] }); |
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.
Since Record<never, never>
is just {}
with this PR those are expected here. Those unions were reduced to just string
and thus concrete literal strings can no longer be suggested.
Both of those changed locations obey the rule from #49119 :
For backwards compatibility, special exceptions to the T & {} type reduction rules existing for intersections written explicitly as string & {}, number & {}, and bigint & {} (as opposed to created through instantiation of a generic type T & {}).
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.
How is it that this string & Record<never, never>
was being preserved before? Is it because, before this PR, Record<never, never>
was some mapped type and we couldn't do subtype reduction on the intersection?
I'm curious to see if this breaks people, since this is in our tests, but you're right, officially we only support string & {}
explicitly written as so.
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.
Is it because, before this PR, Record<never, never> was some mapped type and we couldn't do subtype reduction on the intersection?
IIRC - yeah, something like that. The type was not reduced to {}
so it stayed as a mapped type and that wasn't reduced. But with this change it's treated like {}
so intersections containing it are way more easily reducible.
@typescript-bot run DT |
Heya @gabritto, I've started to run the parallelized Definitely Typed test suite on this PR at 081619e. You can monitor the build here. Update: The results are in! |
Heya @gabritto, I've started to run the diff-based top-repos suite on this PR at 081619e. You can monitor the build here. Update: The results are in! |
Heya @gabritto, I've started to run the diff-based user code test suite on this PR at 081619e. You can monitor the build here. Update: The results are in! |
Heya @gabritto, I've started to run the regular perf test suite on this PR at 081619e. You can monitor the build here. Update: The results are in! |
@gabritto Here are the results of running the user test suite comparing There were infrastructure failures potentially unrelated to your change:
Otherwise... Something interesting changed - please have a look. Details
|
@gabritto Here they are:
tscComparison Report - baseline..pr
System info unknown
Hosts
Scenarios
tsserverComparison Report - baseline..pr
System info unknown
Hosts
Scenarios
startupComparison Report - baseline..pr
System info unknown
Hosts
Scenarios
Developer Information: |
Hey @gabritto, the results of running the DT tests are ready. Branch only errors:Package: react-aria-live
Package: react-instantsearch-native
Package: reactable
Package: relay-test-utils
Package: react-native-modals
Package: solid__react
Package: react-gateway
Package: react-helmet-with-visor
Package: react-instantsearch-core
Package: dom-css
Package: react-instantsearch
Package: react-switch-case
Package: jest
|
@gabritto Here are the results of running the top-repos suite comparing Something interesting changed - please have a look. Details
|
Seems like there are many breaks on the top repos test :/ |
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.
fixes #56691
This makes non-generic mapped types with
never
constraints behave like{}
(since it displays as{}
). "If it looks like a duck, swims like a duck, and quacks like a duck, then it probably is a duck."