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

TS parameter properties (constructor initializers) are wrongly available in other class fields, differs from babel #7356

Closed
elado opened this issue May 5, 2023 · 4 comments
Labels

Comments

@elado
Copy link

elado commented May 5, 2023

Describe the bug

Seems like constructor(private field: Type) produces code that runs in a different order from Babel, resulting in runtime differences.

The following code:

function createObj(prop: string) {
  console.log(`[createObj] ${prop}`);
  return { prop };
}

class Something {
  private prop: string;
  constructor(private prop: string) {
    this.prop = prop;
    console.log(`[Something] constructor ${this.prop}`);
  }

  private readonly obj = createObj(this.prop);
}

new Something(1)

with Target ES2022 transpiles to

function createObj(prop) {
    console.log(`[createObj] ${prop}`);
    return {
        prop
    };
}
class Something {
    prop;
    constructor(prop){
        this.prop = prop;
        this.obj = createObj(this.prop);
        console.log(`[Something] constructor ${this.prop}`);
    }
    obj;
}
new Something(1);

Running it logs:

[createObj] 1
[Something] constructor 1

Babel, however, transpiles to

function createObj(prop) {
  console.log(`[createObj] ${prop}`);
  return {
    prop
  };
}
class Something {
  constructor(prop) {
    this.prop = prop;
    console.log(`[Something] constructor ${this.prop}`);
  }
  obj = createObj(this.prop); // <--- Left as a class field
}
new Something(1);

and logs show

[createObj] undefined
[Something] constructor 1

because createObj runs before this.prop is assigned.

I'd imagine the spec says to define all class props first, then run constructor, but I'm not entirely sure.

Input code

No response

Config

No response

Playground link

No response

Expected behavior

That this.prop stays undefined when calling createObj.

Actual behavior

No response

Version

1.3.56

Additional context

https://play.swc.rs/?version=1.3.56&code=H4sIAAAAAAAAA2WPMQ7CMAxF95zCA0OzVGKl4gwMjKhS2yiUVCWuHKcMVe6OyxAiGLx8fb3%2FfI%2FesEMPhmzP9jJM1UK4nCAwOT9q2BSAQR9wtvWMY9XdcrOFw7aXU6cbaZHlSB422DNIjUpKmbkPAa74tPwQXKYxRcNIsuVWgcH%2F5u9qZrQlQAwkDHWhkeRwmOBcvJQ7%2BmPl7evrVB21egN0VDpJBgEAAA%3D%3D&config=H4sIAAAAAAAAA1VPOw7DIAzdOQXy3KFi6NA79BCIOhERAYQdqSjK3QsJpM1mv4%2Ff8yqkhIkMPOVaxrJEnQjTuReEsmf9KQhwjkgm2chw6yxTpQbtCHdoOxhgnUbk6kJSd6WaA1wIhN3RsNl6O%2BT%2FTBPmmJDoKqxS7UeH10TRUmEO72Un2y%2B179HgAT9RDzsPg6VXd3JaUGxfBMLf3xcBAAA%3D

@elado elado added the C-bug label May 5, 2023
@kdy1 kdy1 closed this as not planned Won't fix, can't repro, duplicate, stale May 5, 2023
@magic-akari
Copy link
Member

I'd imagine the spec says to define all class props first, then run constructor, but I'm not entirely sure.

I think you are right. The problem is the TypeScript constructor field, which is not part of the JS specification.
I'm not sure what to do with it.

@elado elado changed the title TS constructor fields are wrongly available in other class fields, differs from babel TS parameter properties (constructor initializers) are wrongly available in other class fields, differs from babel May 8, 2023
@elado
Copy link
Author

elado commented May 8, 2023

Since there's no clear spec and babel/tsc/swc all differ on the implementation (also different based on config) I am adding https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/docs/rules/parameter-properties.md to disallow parameter properties in my project.

@swc-bot
Copy link
Collaborator

swc-bot commented Jun 8, 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 Jun 8, 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