diff --git a/packages/babel-helpers/src/helpers.js b/packages/babel-helpers/src/helpers.js index 4397c0f817..73c4e1a4d8 100644 --- a/packages/babel-helpers/src/helpers.js +++ b/packages/babel-helpers/src/helpers.js @@ -617,7 +617,10 @@ helpers.possibleConstructorReturn = helper("7.0.0-beta.0")` export default function _possibleConstructorReturn(self, call) { if (call && (typeof call === "object" || typeof call === "function")) { return call; + } else if (call !== void 0) { + throw new TypeError("Derived constructors may only return object or undefined"); } + return assertThisInitialized(self); } `; diff --git a/packages/babel-plugin-transform-classes/test/fixtures/spec/derived-constructor-no-primitive-return/exec.js b/packages/babel-plugin-transform-classes/test/fixtures/spec/derived-constructor-no-primitive-return/exec.js new file mode 100644 index 0000000000..93ca39b8a6 --- /dev/null +++ b/packages/babel-plugin-transform-classes/test/fixtures/spec/derived-constructor-no-primitive-return/exec.js @@ -0,0 +1,18 @@ +class Bar {} + +class Foo extends Bar { + constructor() { + super(); + return 3; + } +} + +class Foo2 extends Bar { + constructor() { + super(); + return null; + } +} + +expect(() => new Foo()).toThrow("Derived constructors may only return object or undefined"); +expect(() => new Foo2()).toThrow("Derived constructors may only return object or undefined"); diff --git a/packages/babel-plugin-transform-classes/test/fixtures/spec/derived-constructor-no-primitive-return/input.js b/packages/babel-plugin-transform-classes/test/fixtures/spec/derived-constructor-no-primitive-return/input.js new file mode 100644 index 0000000000..bbe205aacb --- /dev/null +++ b/packages/babel-plugin-transform-classes/test/fixtures/spec/derived-constructor-no-primitive-return/input.js @@ -0,0 +1,6 @@ +class Foo extends Bar { + constructor() { + super(); + return 3; + } +} diff --git a/packages/babel-plugin-transform-classes/test/fixtures/spec/derived-constructor-no-primitive-return/output.js b/packages/babel-plugin-transform-classes/test/fixtures/spec/derived-constructor-no-primitive-return/output.js new file mode 100644 index 0000000000..5d5787817e --- /dev/null +++ b/packages/babel-plugin-transform-classes/test/fixtures/spec/derived-constructor-no-primitive-return/output.js @@ -0,0 +1,17 @@ +var Foo = /*#__PURE__*/function (_Bar) { + "use strict"; + + babelHelpers.inherits(Foo, _Bar); + + var _super = babelHelpers.createSuper(Foo); + + function Foo() { + var _this; + + babelHelpers.classCallCheck(this, Foo); + _this = _super.call(this); + return babelHelpers.possibleConstructorReturn(_this, 3); + } + + return Foo; +}(Bar); diff --git a/packages/babel-plugin-transform-classes/test/fixtures/spec/returning-from-derived-constructor/exec.js b/packages/babel-plugin-transform-classes/test/fixtures/spec/returning-from-derived-constructor/exec.js index 8913b1a38a..2b445a8740 100644 --- a/packages/babel-plugin-transform-classes/test/fixtures/spec/returning-from-derived-constructor/exec.js +++ b/packages/babel-plugin-transform-classes/test/fixtures/spec/returning-from-derived-constructor/exec.js @@ -43,16 +43,16 @@ expect(instance).toBe(singleton); instance = new Sub; expect(instance).toBe(singleton); -class Null extends Foo { +class Undefined extends Foo { constructor() { if (false) { super(); } - return null; + return; super(); } } expect(() => { - new Null(); + new Undefined(); }).toThrow("this");