Skip to content

Fix empty object intersections#28429

Merged
ahejlsberg merged 5 commits intomasterfrom
fixEmptyObjectIntersection
Nov 10, 2018
Merged

Fix empty object intersections#28429
ahejlsberg merged 5 commits intomasterfrom
fixEmptyObjectIntersection

Conversation

@ahejlsberg
Copy link
Copy Markdown
Member

With this PR we properly preserve the origin of empty object literal types in intersections such that the logic that automatically infers index signatures for object literal types continues to work.

Fixes #20225.
Fixes #27044.

Copy link
Copy Markdown
Member

@weswigham weswigham left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will actually have a perf impact, too - rather than, say, a single {} & string intersection type existing, we'll have a {} & string for every empty object type made (that eventually gets intersected). That's how nonempty objects work, so not surprising - just a remark that it could affect performance in some way. Probably not much, since most {} in intersections I'd guess are the {} made in the compiler and used as the base constraint/inference failure type... But everwhere someone's written T={} (which is pretty often in a lot of the react stuff I've seen), we'll now be manufacturing new intersection identities.

Comment thread src/compiler/checker.ts
if (getObjectFlags(type) & ObjectFlags.Anonymous && isEmptyObjectType(type)) {
includes |= TypeFlags.EmptyObject;
if (isEmptyAnonymousObjectType(type)) {
if (!(includes & TypeFlags.EmptyObject)) {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's never a situation where we'd need to preserve multiple different empty types... Right?

@ahejlsberg
Copy link
Copy Markdown
Member Author

I don't expect this to affect performance in any measurable way.

Regarding preservation of multiple empty object types, there are just two facts that matter for empty object types in intersections, one being whether the intersection contains any empty object types, and the other being whether any of those object types originate in an object literal type (for which we can automatically infer an index signature). We didn't track the second fact at all before. With this PR we do because we preserve the (first) actual empty object type as opposed to substituting our generic emptyObjectType. Now, technically we should track whether any (instead of the first) empty object type originated in an object literal type, but I honestly think this fix is good enough.

@weswigham
Copy link
Copy Markdown
Member

Theoretically there's also the JSLiteral and JSXAttributes object flags (which can both appear on empty object literal types from JS files and jsx attributes, respectively) that affect noImplicitAny and excess property errors, respectively.

@ahejlsberg ahejlsberg merged commit a2205ad into master Nov 10, 2018
@ahejlsberg ahejlsberg deleted the fixEmptyObjectIntersection branch November 10, 2018 08:45
@microsoft microsoft locked as resolved and limited conversation to collaborators Oct 21, 2025
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants