Description
TypeScript Version: 3.2.1
Search Terms: empty class property properties declared defined not initialized undefined
Code
// A *self-contained* demonstration of the problem follows...
// Test this by running `tsc` on the command-line, rather than through another build tool such as Gulp, Webpack, etc.
class Foo {
property: string;
}
const foo = new Foo;
console.log('property' in Foo); // should be `true`
Expected behavior:
According to the class fields proposal, property
should be initialized as undefined
, as it does not have an initializer.
Considering that TypeScript wants to be a superset of JS, this is a problem and would be a breaking change.
I would really like to know what you think the golden path forward is here. When using @babel/plugin-transform-typescript
with @babel/plugin-proposal-class-properties
, the latter one has to be run first, otherwise the following code would behave incorrectly (taken from ember-cli-typescript
):
class TestClass {
// we shouldn't encourage folks to write code like this, but tsc ensures
// that constructor param fields are set before field initializers run
field = this.constructorParam;
constructor(private constructorParam: string) {}
}
let instance = new TestClass('hello');
assert.equal(instance.field, 'hello');
But by running that transform first, the empty class property
gets transformed to spec compliant this.property = undefined;
.
This is a big problem, when dealing with derived classes that (re-)declare fields of base classes without defining them, as these would get transformed to defining them as undefined
.
I know this is a somewhat unsupported setup, but TypeScript is diverging from the planned state of JS and I think this spec incompliancy, if intentional, should at least be explicitly documented and then "fixed" in Babel-land.
Actual behavior:
Class fields without initializers are stripped during transpilation.
Playground Link: Playground
Related Issues: