-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Description
Is there some config to get SWC to emit original authentic TS parameter properties?
I found that using TS parameter properties in SWC leads to JS emit that deviates from what TS produces and deviates from JS semantics. Specifically, when this TS feature is detected in a given class, SWC relocates all field initializers for that class into the constructor body.
Please note this is not about older JS versions or older TS modes. This is the behavior when not down-levelling and when ensuring useDefineForClassFields: true - which is enabled by default in TS when target: es2022 or target: esnext. So I'm asking about the most modern/minimal of output.
TypeScript Compilation
With tsc, field initializers are not relocated.
| Source | TS emit |
|---|---|
class TypeScriptParameterProperties {
initializedField = this.pp;
constructor(public pp: any) {
console.log('finally');
}
} |
class TypeScriptParameterProperties {
pp;
initializedField = this.pp;
constructor(pp) {
this.pp = pp;
console.log("finally");
}
} |
TS Playground link StackBlitz ilnk
SWC Compilation
With swc, field initializers are relocated into the constructor if (and only if) the class uses TS parameter properties.
| Source | SWC emit |
|---|---|
class TypeScriptParameterProperties {
initializedField = this.pp;
constructor(public pp: any) {
console.log('finally');
}
} |
class TypeScriptParameterProperties {
pp;
initializedField;
constructor(pp){
this.pp = pp;
this.initializedField = this.pp;
console.log("finally");
}
} |
Conclusion
Based on history from @magic-akari it looks like this is intentional to have Swc-specific behavior. Which is Swc's choice to make - there is no spec or compliance test suite for this TS-specific feature.
For projects that want to preserve JS semantics and also want to match the official TypeScript output (e.g. in Node's experimental TS support), is there a way to do so? If not, then please consider this to be a polite feature request for a new mode, e.g. "jsc.transform.noInitializerRelocation"