-
Notifications
You must be signed in to change notification settings - Fork 12.5k
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
Optimize the transformed output of JSXSpreadAttribute
s containing an ObjectLiteralExpression
#49100
Optimize the transformed output of JSXSpreadAttribute
s containing an ObjectLiteralExpression
#49100
Conversation
…n `ObjectLiteralExpression`
1aa7f10
to
1e8ec38
Compare
src/compiler/transformers/jsx.ts
Outdated
function transformJsxSpreadAttributeToSpreadAssignment(node: JsxSpreadAttribute) { | ||
function transformJsxSpreadAttributeToProps(node: JsxSpreadAttribute) { | ||
if (isObjectLiteralExpression(node.expression)) { | ||
return node.expression.properties; |
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 isn't like 100% correct when it comes to JS semantics, but TS never was 100% correct anyway (eg. TS doesn't emit 100% spec-compliant output for a case like this).
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.
What isn't correct about it?
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 this should be OK for the "sane code" but probably once you start thinking about malicious getters, setters, and stuff then you could figure out some edge case that would change behavior with this change. But then it means that the code compiled with TS doesn't work exactly the same as the code compiled with Babel because Babel applies this optimization.
As mentioned though... TS isn't 100% correct even today so I'm not sure if a super subtle (and only for weird code) behavior change changes the "final balance" all that much.
TS is using Object.assign
semantics for spreads (and that calls setters on the target object), whereas the correct semantic is to define properties (and that doesn't call setters). There are also cases like in the referenced Babel PR:
var p = { a: 1 }
var classicAssign = Object.assign({}, { get nefariousGetter() { (p = { evil: 'muahauhauha' }); return 42 } }, { p }) // {"nefariousGetter":42,"p":{"a":1}}
var correct = { ...{ get nefariousGetter() { (p = { evil: 'muahauhauha' }); return 42 } }, p } // {"nefariousGetter":42,"p":{"evil":"muahauhauha"}}
😅
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 needs tests (and to appropriately handle) the __proto__
and "__proto__"
property names, like was mentioned in the original issue. Especially since babel patched the bug in their output, and now skips this inlining when such a property is present :)
…ttribute # Conflicts: # src/compiler/transformers/jsx.ts
The TypeScript team hasn't accepted the linked issue #49099. If you can get it accepted, this PR will have a better chance of being reviewed. |
@weswigham I fixed the issue with |
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 this looks fine and meets what we set out to do now~
closes #49099