-
Notifications
You must be signed in to change notification settings - Fork 12.6k
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
Overriding an accessor with a property causes runtime error when emitting ESNExt #31225
Comments
I cannot get the error (neither using 3.3.3333 or newer version): I get the same generated result as the link posted by AlCalzone. Can you post your |
I made a mistake in the original reproduction code -- I condensed an example from a more complex problem that I thought would be representative but mistakenly thought that my base class had an The
|
Since you asked, I just copied in a tsconfig from another project: {
"compilerOptions": {
"alwaysStrict": true,
"allowSyntheticDefaultImports": true,
"emitDecoratorMetadata": true,
"esModuleInterop": true,
"experimentalDecorators": true,
"lib": [
"es2016",
"dom"
],
"module": "esnext",
"moduleResolution": "node",
"noImplicitAny": true,
"noImplicitThis": true,
"noUnusedLocals": true,
"sourceMap": true,
"strictNullChecks": true,
"target": "esnext"
},
} and the output looks like "use strict";
class Animal {
constructor(name) {
this.name = name;
}
get legs() { return -1; }
move(distanceInMeters = 0) {
console.log(`${this.name} moved ${distanceInMeters}m.`);
}
}
class Snake extends Animal {
get legs() { return 0; } // Correct implementation of abstract superclass property
constructor(name) { super(name); }
move(distanceInMeters = 5) {
console.log("Slithering...");
super.move(distanceInMeters);
}
}
class Horse extends Animal {
constructor(name) {
super(name);
this.legs = 4; // Works when using helper code to emulate pre-ES6 classes, fails with actual ES6
}
move(distanceInMeters = 45) {
console.log("Galloping...");
super.move(distanceInMeters);
}
}
let sam = new Snake("Sammy the Python");
let tom = new Horse("Tommy the Palomino");
sam.move();
tom.move(34);
//# sourceMappingURL=main.js.map |
I just looked at AlCalzone's link. That's very handy thanks! If you make the same change there, giving |
Looks like our es6-classes-but-no-class-fields downlevel emit needs a slight change - we need to overwrite the getter/setter on the superclass with the property defined (rather than completely erasing the field). This is probably best done as a followup to #30467 and #30829 as part of overhauling our field semantics to match the spec a bit better. |
Until that feature gets added to the official playground, you could use this playground instead which has that feature: |
Does milestone modification count as "activity"? I don't want the stale-bot to eat this, it bit me again today. |
@sandersn would this be related to the work we were discussing for the |
My current plan is to start issuing these as suggestions with a codefix when class fields reach stage 4. However, the code is error-prone and suspect, so it might be better to
In addition, pretty large corpora of code haven't shown more than a few instances of the error. That means that a codefix is lower priority since the error on its own is sufficient for new code that's being written. @rbuckton We have plenty of time before 3.9, so maybe we should just turn the error on and see if we run into problems. What do you think? |
We've been reporting this as an error since at least 4.0. I think we can close this. |
TypeScript Version: 3.3.3333 and whatever is on Playground
Search Terms: subclass getter accessor
Code
Expected behavior: Compiler should flag the redeclaration of the getter member as a non-accessor (normal) property, at least when emitting ES6.
Actual behavior: Compiler is fine, but assignment (
this.legs = 4
) fails at runtime with error about assigning to a member with getter but no setter.Playground Link: You can paste the above into Playground to see that there are no compile-time errors but the emitted JS does not demonstrate the error because as far as I can tell, you can't tell Playground to emit ES6. (That would be a nice feature; maybe I should put in a ticket for that?)
Related Issues: none that I could find
ETA: I mistakenly had this with an
abstract
getter to start with. This does not show the buggy behavior because ES6 doesn't have a concept of abstract, so the getter isn't actually defined in the generated parent class at all. The updated code above has an implementation for the getter in the base class and should show the behavior I'm talking about -- I compile it withtarget: 'esnext'
but I imagine it should work withtarget: 'es2015'
also.The text was updated successfully, but these errors were encountered: