-
Notifications
You must be signed in to change notification settings - Fork 12.3k
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
Incorrect class #private fields initialization order with target ES2022 and useDefineForClassFields set to false #54206
Comments
Still an issue in 5.1.3. |
I don't think this is supposed to work. The fact that private fields were transpiled to an assignment inside the constructor seems like a bug, because |
That's fine as long as there is an error produced on compilation time. Having this quietly passing produces a lot of hard to understand issues on run-time. |
Any updates on compilation errors / order fix? |
Same on 5.1.6. |
@Josh-Cena if this is the expected behavior, I think that, at least, should be a compilation error.... class Buzz {
wow = 'one'
}
class Foo {
#bar = this.buz.wow;
^^^_ This is property is uninitialized... or something similar
constructor(private buz: Buzz) {}
}
new Foo(new Buzz()) |
I think this is supposed to work, but we didn't handle this case correctly when private fields were introduced. The ideal solution would be for parameter properties to work with both private fields and
Prior to the adoption of private names, the TypeScript emit followed (1), which I believe is still the best approach. If we want to correctly preserve these semantics and this evaluation order in the presence of private names or
This means moving the field initializers into the constructor body: // source
class C {
y = this.x;
#z = this.y;
constructor(public x) {}
}
// transpiled
class C {
x;
y;
#z;
constructor(x) {
this.x = x;
this.y = this.x;
this.#z = this.y;
}
} |
That's the behavior I expected. Cool to know it's an unexpected breaking change, and this issue is someting fixable π |
5.3.2 still affected |
I forgot to mention a small workaround I wrote couple months ago. It's possible to detect wrongly defined properties using
Hope this helps someone to prevent runtime issues. |
No change in 5.4.3 |
5.5.2 also affected |
Bug Report
π Search Terms
ES2022 class field initialization order
private fields order
useDefineForClassFields false
π Version & Regression Information
β― Playground Link
5.0.4 with runtime error (useDefineForClassFields: false, target: ES2022)
4.9.5 without runtime error (useDefineForClassFields: false, target: ES2022)
π» Code
π Actual behavior
With 5.0.4 and useDefineForClassFields: false, target: ES2022 the above code fails in runtime because
#bar = this.buz.wow;
stays initialized before constructor, this doesn't happen if "normal private" is used (private bar = this.buz.wow;
). Such construct works without issues on 4.9.5.π Expected behavior
The initialization is done in the same way as on 4.9.5.
The text was updated successfully, but these errors were encountered: