Typescript: Instance properties declaration and initialization in constructor failed with useDefineForClassFields turned on

Created on 6 Nov 2019  路  5Comments  路  Source: microsoft/TypeScript

TypeScript Version: 3.7.2

Search Terms: useDefineForClassFields, constructor

Code

class Test {
    constructor(public readonly something: number) { }
}

const k = new Test(5);

Expected behavior: I expect k.something to be 5

Actual behavior: k.something is undefined, cause TS:

  1. writes the value to the property (as it was before)
  2. and then rewrite it (with writable: true, I think it is bug too) to void 0
class Test {
    constructor(something) {
        this.something = something;
        Object.defineProperty(this, "something", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: void 0
        });
    }
}

Playground Link: https://www.typescriptlang.org/play/?useDefineForClassFields=true&target=7&ssl=3&ssc=2&pln=1&pc=1#code/MYGwhgzhAEAqCmEAu0DeAoaXrAPYDtkAnAV2CVyIAoAHEgIxAEthoj4wATAkAT2gi4AtvCQALJvgDmALmj4SQ+vCIBKNNAC+6TUA

Bug Fix Available Fixed High Priority

Most helpful comment

writable: true is intentional; readonly properties may be reassigned multiple times in the constructor body.

The order is definitely wrong though

All 5 comments

writable: true is intentional; readonly properties may be reassigned multiple times in the constructor body.

The order is definitely wrong though

Yeah this is a massive issue. It makes useDefineForClassFields: true unusable.

for now, you can avoid it by using this solution

class Test {
    readyonly something: number
    constructor(something: number) {
        this.something = something 
}
}

code above will fix the wrong ordering of definition

code playground: https://www.typescriptlang.org/play/?useDefineForClassFields=true&target=7&ssl=10&ssc=2&pln=5&pc=1#code/MYGwhgzhAEAqCmEAu0DeAoaXrAPYDtkAnAV2CVyIAoAHEgIxAEthoj4wATAkAT2gi4AtvCQALJvgDmALmj4SQ+vCIBKNNAC+6belCQYAQXy5xKhMjSYs7Lj36CR4yVICEchUpXWseQklJySipHUQlpD0VlNStsOOhnCAA6UOdpaABeAWEwlx8sbU0gA

Hi @RyanCavanaugh, I found a bug, maybe related to this issue. When creating a class with a read-only property, the value is assigned with a variable with the same name as the property. However, this is an error in strict mode, because those variables are not defined.

https://www.typescriptlang.org/v2/en/play?useDefineForClassFields=true#code/MYGwhgzhAEAqCWAXEBTAyigTgN3sF0A3gFDTSYpgAmA9gHYgCe0iSqA-AFzQSKbx0A5gG5S0OmAC2KLjz4CRxMcHq9MAV2CIamABQVq9JtAAWlKlm5qFASiJiAvsQdA

You can confirm it happens only with read-only properties.

@michaeljota It looks like a bug. Here's a smaller repro:

// @useDefineForClassFields: true
class TitleService {
  readonly title?: string;
}

I filed #36910 to track it.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

bgrieder picture bgrieder  路  3Comments

DanielRosenwasser picture DanielRosenwasser  路  3Comments

weswigham picture weswigham  路  3Comments

dlaberge picture dlaberge  路  3Comments

manekinekko picture manekinekko  路  3Comments