Using fields defined by Constructor Shorthand in Field Initializer

143 views Asked by At

I'm currently having issues after compiling my code to JS which do not happen when running the same code in ts-node.

Assuming following code :

class A {
  constructor(readonly parameterProperty: number) {}
  readonly fieldInitializer = this.parameterProperty * 10;
}

It seems that ts-node first initializes the parameterProperty, then initializes the field with the already created value. The compiled JS code however first tries to initialize the field, then the parameterProperty. Compiled JS:

"use strict";
class A {
    parameterProperty;
    constructor(parameterProperty) {
        this.parameterProperty = parameterProperty;
    }
    fieldInitializer = this.parameterProperty * 10;
}

I'm wondering if this means using parameterProperties in this fashion is not intended. Sadly I was not able to find anything about the initialization order of these in the Docs.

TSconfig wise I am using :

 "target": "ES2022",                         
 "module": "CommonJS",
 "emitDecoratorMetadata": true,
 "experimentalDecorators": true,
 "esModuleInterop":true,

I've actually found a solution to getting the compiled code behave just as when beeing run with ts-node. Since I spend a few hours searching I want to document this here anyways though.

1

There are 1 answers

1
Aderion On BEST ANSWER

So, following result after searching and playing around in the TS-Playground.

Following setting changes the behaviour of the initialization order.

"useDefineForClassFields": false

Code beeing emitted with this disabled is:

"use strict";
class A {
    constructor(parameterProperty) {
        this.parameterProperty = parameterProperty;
        this.fieldInitializer = this.parameterProperty * 10;
    }
}

With this enabled the code looks like this:

"use strict";
class A {
    parameterProperty;
    constructor(parameterProperty) {
        this.parameterProperty = parameterProperty;
    }
    fieldInitializer = this.parameterProperty * 10;
}

Which thus changes the initialization order to first initialize the fields, then the parameterProperties.

Apparently this setting is true by default.