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

Error when compiled JavaScript initializes static properties in a class with a hard private method (#) that references a static property #58244

Open
nolan-white opened this issue Apr 18, 2024 · 0 comments
Assignees
Labels
Needs Investigation This issue needs a team member to investigate its status.

Comments

@nolan-white
Copy link

πŸ”Ž Search Terms

private methods, hard private, #, static properties, compile output, es2022

πŸ•— Version & Regression Information

This changed between versions 5.1.6 and 5.2.2

⏯ Playground Link

https://www.typescriptlang.org/play?target=9&module=7&ts=5.4.5#code/MYGwhgzhAEAqCmEAu0DeAoaXrLEglsNAE7xgAmA9gHYgCe0AcgIICyAotALzQDkA7pWIhyvTNlwEipCjXrQOAZUXMA4px4ADABLwQIStAAkqBMgB0LDgF8AhJvFYAxAFs6ABWL4Abnnit4JAALSnIACgBKNEdsLGAaCEoQeHMDAHMwsyRzJRV1CIBuGOt0ayA

πŸ’» Code

class Test {
    static readonly NAME = 'world'
    static readonly MESSAGE = `Hello ${Test.NAME}!`
    #myPrivateMethod() {
        console.log(Test.MESSAGE);
    }
}

compiles to

"use strict";
var _a;
class Test {
    static { this.NAME = 'world'; }
    static { this.MESSAGE = `Hello ${_a.NAME}!`; } // _a is undefined here
    #myPrivateMethod() {
        console.log(_a.MESSAGE);
    }
}
_a = Test;

πŸ™ Actual behavior

If a class has a hard private method (#) that accesses a static property of the class when the target is ES2022, the compiled JavaScript will declare a module-level variable before the class is declared that is assigned the class's constructor after the class is declared. This variable is substituted in for the explicit class constructor anywhere it is used in the class declaration. If the class declaration has any static properties that reference other static properties of the class during their initialization, an error will be thrown because the module-level variable being used in place of the class constructor is undefined until the class declaration is complete.

πŸ™‚ Expected behavior

If a class has a hard private method (#) that accesses a static property of the class when the target is ES2022, the compiled JavaScript uses the actual constructor in the class declaration like it did in TypeScript 5.1.6, or at least uses it when it is referenced during the initialization of the class's static properties.

Example of expected compiled JavaScript:

"use strict";
class Test {
    static { this.NAME = 'world'; }
    static { this.MESSAGE = `Hello ${Test.NAME}!`; }
    #myPrivateMethod() {
        console.log(Test.MESSAGE);
    }
}

Additional information about the issue

Workaround for the time being is to set target in tsconfig.json to 'ESNext'. This produces the expected behavior.

@RyanCavanaugh RyanCavanaugh added the Needs Investigation This issue needs a team member to investigate its status. label Apr 18, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Needs Investigation This issue needs a team member to investigate its status.
Projects
None yet
Development

No branches or pull requests

3 participants