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

swc generates a different prototype chain than tsc #7357

Closed
rafaelliu opened this issue May 5, 2023 · 5 comments
Closed

swc generates a different prototype chain than tsc #7357

rafaelliu opened this issue May 5, 2023 · 5 comments
Labels

Comments

@rafaelliu
Copy link

Describe the bug

The way swc defines class properties generates a different prototype chain from tsc, with semantic differences.

swc uses Object.defineProperty to define a property (even if not initialized) at the class object, while tsc either doesn't define any property (if it's not initialized) or initializes it with this.

One issue is user-define properties defined elsewhere in the prototype chain are never reached. Also, the initialization of the property for a code compiled with tsc will use any current set accessor (or an error will be throw if none is set).

Input code

class MyClass {
   myProp: number;
}

Object.defineProperty(MyClass.prototype, 'myProp', { value: 42 })
console.log(new MyClass().myProp)


### Config

```json
Using ts-node with `swc: true`

Playground link

No response

Expected behavior

same as tsc, generate a JS not defining any property:

let MyClass = class MyClass {
};
export { MyClass };

Which prints "42"

Actual behavior

swc generates a property, and will use Object.defineProperty:

export let MyClass = class MyClass {
    constructor(){
        _define_property(this, "myProp", void 0);
    }
};

Which prints "undefined"

Version

1.3.56

Additional context

Even when initializing the property, tsc is more flexible in that it uses this:

let MyClass = class MyClass {
    constructor() {
        this.componentManager = 42;
    }
};
export { MyClass };

swc:

export let MyClass = class MyClass {
    constructor(){
        _define_property(this, "myProp", 42);
    }
};
@rafaelliu rafaelliu 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
@rafaelliu
Copy link
Author

Hi @kdy1, it took a while to troubleshoot the issue, and then some more to report it compiling different cases and comparing outputs.

I understand its your prerogative to choose what goes and what doesn’t go into swc, but would you care provide a word or two?

@kdy1
Copy link
Member

kdy1 commented May 7, 2023

@rafaelliu Search before filing an issue.

@TiddoLangerak
Copy link

For future reference, as this issue is a dead end at the moment.

The behaviour can be toggled by disabling the useDefineForClassFields option.

@rafaelliu
Copy link
Author

Following @TiddoLangerak spirit of collaboration, the problem is ts-node doesn’t allow that to be set. There’s a PR open, original issue here: TypeStrong/ts-node#1856

This wasn’t the default for swc and used to work, but it changed on version 1.3.39 which broke things.

@swc-bot
Copy link
Collaborator

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