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:
writable: true, I think it is bug too) to void 0class 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
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.
Most helpful comment
writable: trueis intentional;readonlyproperties may be reassigned multiple times in the constructor body.The order is definitely wrong though