-
Notifications
You must be signed in to change notification settings - Fork 13.2k
Closed
Labels
BugA bug in TypeScriptA bug in TypeScriptFix AvailableA PR has been opened for this issueA PR has been opened for this issueHelp WantedYou can do thisYou can do this
Milestone
Description
TypeScript Version: 3.7 - 4.1.0-dev.20200918
Search Terms:
abstract properties emit useDefineForClassFields
Code
Turn on useDefineForClassFields
abstract class A {
protected abstract x: number;
}Expected behavior:
Abstract members are hint for typescript and they don't emit any code. So expected compiled code will be:
"use strict";
class A {
}Actual behavior:
"use strict";
class A {
constructor() {
Object.defineProperty(this, "x", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
}
}Consequence of such generation:
There is a larger problem caused by compiling abstract member.
There are 2 ways of override - using property or using getter/setter and they both should be (and are according to ts) compatible with abstract member. But only one of them is fine in runtime.
Code
Turn on useDefineForClassFields
abstract class A {
protected readonly abstract x: number;
public doSmth() {
console.log(this.x)
}
}
class B extends A {
protected x = 10
}
class C extends A {
protected get x() { return 7 }
}
new B().doSmth()
new C().doSmth()Run compiled code
Expected behavior:
Output:
10
7
Compiled code:
"use strict";
class A {
doSmth() {
console.log(this.x);
}
}
class B extends A {
constructor() {
super(...arguments);
Object.defineProperty(this, "x", {
enumerable: true,
configurable: true,
writable: true,
value: 10
});
}
}
class C extends A {
get x() { return 7; }
}
new B().doSmth();
new C().doSmth();Actual behavior:
Ouptut:
10
undefined
Compiled code:
"use strict";
class A {
constructor() {
Object.defineProperty(this, "x", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
}
doSmth() {
console.log(this.x);
}
}
class B extends A {
constructor() {
super(...arguments);
Object.defineProperty(this, "x", {
enumerable: true,
configurable: true,
writable: true,
value: 10
});
}
}
class C extends A {
get x() { return 7; }
}
new B().doSmth();
new C().doSmth();Related Issues:
#31225
Metadata
Metadata
Assignees
Labels
BugA bug in TypeScriptA bug in TypeScriptFix AvailableA PR has been opened for this issueA PR has been opened for this issueHelp WantedYou can do thisYou can do this