-
Notifications
You must be signed in to change notification settings - Fork 12.7k
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
Class field initialization order different between target ES2021 and ES2022 #52331
Comments
Related: #50971 |
I don't think we can change the emit here, but giving a correct error under |
So I understand that we must change our code when we want to target es2022. Unfortunately we rely on the initialization order in lots of places all over the code-base. |
I'm not sure if this also falls under class API {
private _state = this.initialState();
constructor(private storage: Map<string, unknown>) {}
initialState() {
return this.storage.get("anything");
}
} This is arguably, to me at least, an example where the |
It's really unclear how you'd detect that except by checking the method bodies n times where at each n = k you pretend that only the first |
Maybe it's better as a lint rule 🤷 ? False positives could at least be ignored then. Something about calling methods from class field properties that reference constructor shorthand-defined properties... It's really too bad that this is how the ES2022 spec defines the execution order, as it seems to break a lot of existing TS code. For now our workaround will be |
* ES2022 额外规定了类属性的初始化顺序行为,与 TypeScript 原有行为有差异 - microsoft/TypeScript#52331 - 目前通过配置 `"useDefineForClassFields": false` 保证行为的兼容性
…t to feature/next * commit '880e0864f400a56bfc571709be41f7eb6316b551': update: FXD-64717 解决 ES2022 属性初始化顺序问题 * ES2022 额外规定了类属性的初始化顺序行为,与 TypeScript 原有行为有差异 - microsoft/TypeScript#52331 - 目前通过配置 `"useDefineForClassFields": false` 保证行为的兼容性 update: FXD-64717 升级 nstarter-entity -> 0.4.0
Bug Report
🔎 Search Terms
ES2022 class field initialization order
🕗 Version & Regression Information
⏯ Playground Link
Playground link with relevant code
💻 Code
🙁 Actual behavior
If the compiler is set to target "ES2021" then the output will be:
If the target is set to "ES2022" then the output will be:
These look logically the same, just utilizing the field syntax in Javascript, but in Javascript fields are initialized BEFORE the constructor is run.
So that means that ES2021 will work, setting the
param
field onTest
and then use it to set thea
field, but with ES2022 it will attempt to seta
first, using theparam
field which has not been initialized yet, thus throwing an error at runtime.There is no warning or error that this will happen, and I could not find any kind of compiler flag to enable such an error. Even "strictPropertyInitialization" didn't catch this like I thought it might.
🙂 Expected behavior
In order to maintain Javascript semantics, I believe that Typescript should not allow field initializers to access these automatic field setting constructor parameters. Typescript should not allow you to do something that will simply not work.
Alternatively, the compiler could be changed to insert the initializer at the end of the constructor. This would maintain existing Typescript behavior at the expense of being different from Javascript.
The text was updated successfully, but these errors were encountered: