Include decorator and class field plugins after TypeScript, if present #311
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Babel now has an official stance on the order the TS plugin should be added relative to any others that touch certain class features, and an assertion is tripped when attempting to use TS's new
declare
field syntax:What breaks
Before, both
ember-cli-typescript
andember-cli-babel
ensured that@babel/plugin-transform-typescript
would appear after anything that touched class fields, because it maintained the edge-case semantics oftsc
that initializes 'constructor fields' before regular class fields:These semantics aren't actually possible with native class fields, but
tsc
doesn't yet support that as a compilation target and hasn't had to deal with the inconsistency.With the plugins in the order Babel now asserts they should be in, Babel transpilation now gives you:
There should hopefully be little to no actual usage of this pattern in Ember TypeScript code in the wild, but it's not an easy condition to search for.
Non-TypeScript code wouldn't be impacted, since constructor fields aren't an ES feature.
What's fixed
The
declare
field modifier is the answer to a stumbling block that a lot of devs hit with the class fields spec, which dictates thatfoo;
in a class body initializes that field toundefined
during construction. This leaves TS authors without a clean way to declare the type of a class field without implicitly adding anundefined
initializer for it, which is why thedeclare
modifier was introduced.While
declare
is the piece of syntax that currently triggers the plugin ordering assertion, given the way the TS plugin interacts with other class features, it's likely others will be introduced in the future as both languages evolve.Why ember-cli-babel needs a change
In
ember-cli-typescript
we can ensure that the ordering is correct if the decorator or class-property plugins are already in the list as user-supplied configuration, but whenember-cli-babel
adds them, it happens after we've had our chance to set configuration, so we can't control the ordering ourselves.While this is technically a breaking change for anyone whose code relies on the constructor/class field initialization order, the impact will hopefully be minimal. I'd guess it will hit fewer folks than #307, so I'm hopeful we can get away with it.