diff --git a/packages/babel-helper-create-class-features-plugin/src/index.js b/packages/babel-helper-create-class-features-plugin/src/index.js index 760be4af9657..1879bb0ba3bb 100644 --- a/packages/babel-helper-create-class-features-plugin/src/index.js +++ b/packages/babel-helper-create-class-features-plugin/src/index.js @@ -21,7 +21,7 @@ import { import pkg from "../package.json"; -export { FEATURES }; +export { FEATURES, injectInitialization }; // Note: Versions are represented as an integer. e.g. 7.1.5 is represented // as 70000100005. This method is easier than using a semver-parsing diff --git a/packages/babel-plugin-transform-typescript/package.json b/packages/babel-plugin-transform-typescript/package.json index ed2c5157cf6f..ff5755d6b319 100644 --- a/packages/babel-plugin-transform-typescript/package.json +++ b/packages/babel-plugin-transform-typescript/package.json @@ -13,6 +13,7 @@ "typescript" ], "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.3.4", "@babel/helper-plugin-utils": "^7.0.0", "@babel/plugin-syntax-typescript": "^7.2.0" }, diff --git a/packages/babel-plugin-transform-typescript/src/index.js b/packages/babel-plugin-transform-typescript/src/index.js index 149c7f1050d6..14f89d34575f 100644 --- a/packages/babel-plugin-transform-typescript/src/index.js +++ b/packages/babel-plugin-transform-typescript/src/index.js @@ -1,6 +1,7 @@ import { declare } from "@babel/helper-plugin-utils"; import syntaxTypeScript from "@babel/plugin-syntax-typescript"; -import { types as t } from "@babel/core"; +import { types as t, template } from "@babel/core"; +import { injectInitialization } from "@babel/helper-create-class-features-plugin"; import transpileEnum from "./enum"; @@ -175,41 +176,21 @@ export default declare((api, { jsxPragma = "React" }) => { if (parameterProperties.length) { const assigns = parameterProperties.map(p => { - let name; + let id; if (t.isIdentifier(p)) { - name = p.name; + id = p; } else if (t.isAssignmentPattern(p) && t.isIdentifier(p.left)) { - name = p.left.name; + id = p.left; } else { throw path.buildCodeFrameError( "Parameter properties can not be destructuring patterns.", ); } - const assign = t.assignmentExpression( - "=", - t.memberExpression(t.thisExpression(), t.identifier(name)), - t.identifier(name), - ); - return t.expressionStatement(assign); + return template.statement.ast`this.${id} = ${id}`; }); - const statements = childNode.body.body; - - const first = statements[0]; - - const startsWithSuperCall = - first !== undefined && - t.isExpressionStatement(first) && - t.isCallExpression(first.expression) && - t.isSuper(first.expression.callee); - - // Make sure to put parameter properties *after* the `super` - // call. TypeScript will enforce that a 'super()' call is the - // first statement when there are parameter properties. - childNode.body.body = startsWithSuperCall - ? [first, ...assigns, ...statements.slice(1)] - : [...assigns, ...statements]; + injectInitialization(path, child, assigns); } } else if (child.isClassProperty()) { childNode.typeAnnotation = null; diff --git a/packages/babel-plugin-transform-typescript/test/fixtures/class/parameter-properties-late-super/input.js b/packages/babel-plugin-transform-typescript/test/fixtures/class/parameter-properties-late-super/input.js new file mode 100644 index 000000000000..00ec8f809849 --- /dev/null +++ b/packages/babel-plugin-transform-typescript/test/fixtures/class/parameter-properties-late-super/input.js @@ -0,0 +1,9 @@ +class B extends A { + constructor(public p: string) { + console.log('anything before super'); + if (p) super(); + else { + super(); + } + } +} \ No newline at end of file diff --git a/packages/babel-plugin-transform-typescript/test/fixtures/class/parameter-properties-late-super/options.json b/packages/babel-plugin-transform-typescript/test/fixtures/class/parameter-properties-late-super/options.json new file mode 100644 index 000000000000..5c79172a6082 --- /dev/null +++ b/packages/babel-plugin-transform-typescript/test/fixtures/class/parameter-properties-late-super/options.json @@ -0,0 +1,3 @@ +{ + "plugins": ["transform-typescript"] +} diff --git a/packages/babel-plugin-transform-typescript/test/fixtures/class/parameter-properties-late-super/output.js b/packages/babel-plugin-transform-typescript/test/fixtures/class/parameter-properties-late-super/output.js new file mode 100644 index 000000000000..2f5c7109252a --- /dev/null +++ b/packages/babel-plugin-transform-typescript/test/fixtures/class/parameter-properties-late-super/output.js @@ -0,0 +1,14 @@ +class B extends A { + constructor(p) { + console.log('anything before super'); + + if (p) { + super(); + this.p = p; + } else { + super(); + this.p = p; + } + } + +}