-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
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
(fix) Class fields are set to undefined if there's no initializer #3459
(fix) Class fields are set to undefined if there's no initializer #3459
Conversation
If I remeber correctly, this is wrong |
@kdy1 I had a look into this issue and how to fix it while keeping fix for #2127 See 46d4cd8 For #2127 I compiled the same code with SWC, Babel, esbuild and TSC. SWC - ✅ Looks like only SWC and TSC (lower than esnext) supports this at the moment all the others return I read the spec to see if there was a mention of how this should be handled (e.g. no initializer always sets value to However, I found an alternative way to fix #2127 and moved it to If there is no If object does not have own property it will check the prototype chain. |
396f753
to
9644911
Compare
I've pushed my local test bench for this issue which shows how each tool handles both issues https://github.com/williamtetlow/2117-2127-swc-testbench For #2127 the reason this code worked for the issue raiser on |
Oh... Then I think we should follow |
It looks like it's related to This is turned on by default for The issue in #2127 is that the field is defined on ((_class = class TestClass2 {
constructor() {
// defining here hides prototype.constructor.testProperty
_initializerDefineProperty(this, "testProperty", _descriptor, this);
}
})
Going forward tsc will define class fields by default (like swc is doing) but you can override this and not emit by adding class TestClass2 {
@deco public declare testProperty: Date;
} I've added this logic to swc in 813e3eb#diff-8f03d343376a656cd03aec743c8cb8b60d7c1a4de29f48d940be0795c0931235R676 |
I'm not sure if there is a way to opt out of this logic for Ecmascript unless we make a config setting. Should we add setting or are we ok with making #2127 and #960 not work anymore when compiling Ecmascript to better replicate Typescript behaviour? We could add setting to |
Is this PR ready for review/merge? |
@kdy1 yep it's ready 😄 |
crates/swc_ecma_transforms_base/src/helpers/_apply_decorated_descriptor.js
Show resolved
Hide resolved
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.
Thanks!
When could this fix land in Next.js? |
@aboqasem I'll make a PR today. |
@kdy1 Thank you for your effort! |
Did this land on Next.js? |
Description:
Fixes #2117 by returning
null
instead ofvoid 0
for aninitializer
that is not set on property descriptor. See this comment for good description of problemThis caused tests to fail for #2127 but I have provided alternative fix through checking for
declare
modifier on fields that shouldn't be emitted.TS ESNext now emits class fields with no initializer by default. See
useDefineForClassFields
It supports overriding this behaviour through the
declare
modifier.#960 and #2127 should now be solved by using
declare
modifier. Swc will emit class fields by default now to match tsc behaviour.BREAKING CHANGE:
#960
#2127
By default, class fields will be defined and set to
undefined
breaking the two issues above.Fields should have
declare
modifier if they shouldn't be emitted.Related issue (if exists):
#2117
#2127
#960