Skip to content
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

Uninitialized class property is defined with value "void 0" in es2015 #8000

Closed
smvv opened this issue Sep 25, 2023 · 3 comments
Closed

Uninitialized class property is defined with value "void 0" in es2015 #8000

smvv opened this issue Sep 25, 2023 · 3 comments
Labels

Comments

@smvv
Copy link
Contributor

smvv commented Sep 25, 2023

Describe the bug

When transpiling to es2015, swc initializes an uninitialized class property to undefined:

// [...]
class Base {
    constructor(){
        _define_property(this, "data", 1);
    }
}
export class Foo extends Base {
    constructor(...args){
        super(...args);
        _define_property(this, "data", void 0);
    }
}

When es2022 is used, it does not initialize the property:

class Base {
    data = 1;
}
export class Foo extends Base {
    data;
}

Similarly, tsc and esbuild skip the initialization.

Input code

class Base {
  data: number = 1
}

export class Foo extends Base {
    data!: number
}

Config

{
  "jsc": {
    "parser": {
      "syntax": "typescript",
      "tsx": false
    },
    "target": "es2015",
    "loose": false,
    "minify": {
      "compress": false,
      "mangle": false
    }
  },
  "module": {
    "type": "es6"
  },
  "minify": false,
  "isModule": true
}

Playground link

https://play.swc.rs/?version=1.3.87&code=H4sIAAAAAAAAA0vOSSwuVnBKLE5VqOZSUEhJLEm0UsgrzU1KLVKwVTDkquXiSq0oyC8qUUgGq3TLz1dIrShJzUtB0gXRpwjTyFULABjS7aVWAAAA&config=H4sIAAAAAAAAA1VPSQ7CMAy85xWRzxwACQ78gUdEwa2Csil2JaKqfydpk0Jv9iye8SykhDdpeMi5jGWJKhGmfS8IZc%2FqUxDgHJF0MpHh1FmmSg3KEq7QsjHAKo3I1YV0PV9uzQE2BMLuaJgz3gz5P1MHFxMSHYVVqvxo8ZgoWiq48JpWsv1S%2B24N7vAT9bD9MBh6dienCcXyBbnuEC8XAQAA

SWC Info output

No response

Expected behavior

Skip the initialization of uninitialized class properties when target is es2015-2021 output.

It's not initializing to undefined when target is es2022.

Actual behavior

By setting the uninitialized property's value to undefined, it overrides the property value set in the base class.

Version

1.3.87

Additional context

Related issue: #3232

@smvv smvv added the C-bug label Sep 25, 2023
@kdy1
Copy link
Member

kdy1 commented Sep 25, 2023

#7435

@kdy1 kdy1 closed this as not planned Won't fix, can't repro, duplicate, stale Sep 25, 2023
@magic-akari
Copy link
Member

You can run this code in modern browsers with native class support.
You will get undefined.

class Base {
    data = 1;
}
class Foo extends Base {
    data;
}

console.log(new Foo().data); // undefined

TypeScript support class field syntax before it is standardized.
And TypeScript's class field has different semantics with native class field.

This is why useDefineForClassFields exists.
When target is set to es2022 or higher, TypeScript will use native class field semantics.

But you should not rely on the behavior of target default value.
You should always set useDefineForClassFields to true or false explicitly.
Once it works in TypeScript, it will work in swc.

@swc-bot
Copy link
Collaborator

swc-bot commented Oct 25, 2023

This closed issue has been automatically locked because it had no new activity for a month. If you are running into a similar issue, please create a new issue with the steps to reproduce. Thank you.

@swc-project swc-project locked as resolved and limited conversation to collaborators Oct 25, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Development

No branches or pull requests

4 participants