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

Invoking a superclass' constructor doesn't work with Turbopack! #77467

Closed
johansunden opened this issue Mar 24, 2025 · 2 comments
Closed

Invoking a superclass' constructor doesn't work with Turbopack! #77467

johansunden opened this issue Mar 24, 2025 · 2 comments
Labels
linear: turbopack Confirmed issue that is tracked by the Turbopack team. Turbopack Related to Turbopack with Next.js.

Comments

@johansunden
Copy link

Link to the code that reproduces this issue

https://github.com/johansunden/my-app

To Reproduce

I have some JavaScript (well, TypeScript) that behaves differently depending on whether I start my app using Turbopack or Webpack. How this makes any sense I don't know.

I have a class PasswordSignInRequest that extends another class SignInRequest. In the constructor of PasswordSignInRequest the constructor of SignInRequest is invoked using super. The constructor of SignInRequest mutates this. Once the constructor of SignInRequest has been invoked, this in the constructor of PasswordSignInRequest has been mutated if I have started my app using Webpack.

export class PasswordSignInRequest extends SignInRequest implements IPasswordSignInRequest {
    username!: string;
    password!: string;
    totp?: string;

    constructor(data?: IPasswordSignInRequest) {
        super(data);
        this._discriminator = "PasswordSignInRequest";
    }
...
}
export class SignInRequest implements ISignInRequest {

    protected _discriminator: string;

    constructor(data?: ISignInRequest) {
        if (data) {
            for (var property in data) {
                if (data.hasOwnProperty(property))
                    (<any>this)[property] = (<any>data)[property];
            }
        }
        this._discriminator = "SignInRequest";
    }
...
}

Current vs. Expected behavior

Current behavior

If I start my app using Turbopack this in the constructor of PasswordSignInRequest has not been mutated once the constructor of SignInRequest has been invoked.

Expected behavior

I would expect no difference in how this is mutated through the use of super when I start my app using Turbopack compared to Webpack. I would expect this in the constructor of PasswordSignInRequest to have been mutated!

Provide environment information

Operating System:
  Platform: darwin
  Arch: arm64
  Version: Darwin Kernel Version 24.2.0: Fri Dec  6 19:01:59 PST 2024; root:xnu-11215.61.5~2/RELEASE_ARM64_T6000
  Available memory (MB): 32768
  Available CPU cores: 10
Binaries:
  Node: 22.11.0
  npm: 11.2.0
  Yarn: N/A
  pnpm: N/A
Relevant Packages:
  next: 15.2.3 // Latest available version is detected (15.2.3).
  eslint-config-next: 15.2.3
  react: 18.3.1
  react-dom: 18.3.1
  typescript: 5.8.2
Next.js Config:
  output: N/A

Which area(s) are affected? (Select all that apply)

Turbopack

Which stage(s) are affected? (Select all that apply)

next dev (local)

Additional context

No response

@github-actions github-actions bot added the Turbopack Related to Turbopack with Next.js. label Mar 24, 2025
@mischnic mischnic added the linear: turbopack Confirmed issue that is tracked by the Turbopack team. label Apr 1, 2025
@mischnic
Copy link
Contributor

mischnic commented Apr 1, 2025

You need useDefineForClassFields: false in your tsconfig.

Otherwise, the JS output is this

export class SignInRequest {
    _discriminator;
    constructor(data){
        if (data) {
            for(var property in data){
                if (data.hasOwnProperty(property)) {
                    this[property] = data[property];
                }
            }
        }
        this._discriminator = 'SignInRequest';
    }
}
export class PasswordSignInRequest extends SignInRequest {
    username;
    password;
    constructor(data){
        super(data);
        this._discriminator = 'PasswordSignInRequest';
    }
}

which should indeed not set username and password, as they were set in the superclass which doesn't have the fields.

https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-7.html#the-usedefineforclassfields-flag-and-the-declare-property-modifier

cc @kdy1

@kdy1
Copy link
Member

kdy1 commented Apr 2, 2025

https://swc.rs/docs/migrating-from-tsc#usedefineforclassfields

The default behavior of turbopack is correct, in the sense of conforming to the specification. It defaults to the correct behavior because it's a tool that comes out after the correct behavior is clearly defined by the specification.

@kdy1 kdy1 closed this as completed Apr 2, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
linear: turbopack Confirmed issue that is tracked by the Turbopack team. Turbopack Related to Turbopack with Next.js.
Projects
None yet
Development

No branches or pull requests

3 participants