Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Should work when a child class has class properties and no constructor, and transpiling spreads on super. (T7309) #4254

Closed
babel-bot opened this issue Apr 22, 2016 · 3 comments · Fixed by #12722
Labels
help wanted outdated A closed issue/PR that is archived due to age. Recommended to make a new issue

Comments

@babel-bot
Copy link
Collaborator

Issue originally made by Paul Sanchez (basicdays)

Bug information

  • Babel version: 6.7.7
  • Node version: 4.4.2
  • npm version: 3.8.6

Options

babel-plugin-transform-class-properties
babel-plugin-transform-es2015-spread

Input code

class Parent {}

class Child extends Parent {
    prop = 'val';
}

Description

When using class properties on a child class without an explicit constructor, a default constructor is created by Babel that includes a spread in the call in super. This causes a syntax error in Node 4. Here's the transpiled output:

'use strict';

class Parent {}

class Child extends Parent {
        constructor() {
                var _temp;

                return _temp = super(...arguments), this.prop = 'val', _temp;
        }

}

A temporary workaround is to also include babel-plugin-transform-es2015-classes or to explicitly provide constructor() { super() } in the child class.

@babel-bot
Copy link
Collaborator Author

babel-bot commented Jun 28, 2016

Comment originally made by @Kovensky

I encountered this when defining a custom Error, so I made the following test case to demonstrate the issue and the workaround with transform-es2015-classes:

class SomeError extends Error {
  name = 'SomeError'
}

throw new SomeError(...['arguments'])

Output with babel --plugins transform-class-properties,transform-es2015-spread:

class SomeError extends Error {
  constructor(...args) {
    var _temp;

    return _temp = super(...args), this.name = 'SomeError', _temp;
  }

}

throw new (Function.prototype.bind.apply(SomeError, [null].concat(['arguments'])))();

Adding transform-es2015-parameters plugin as well to make sure constructor(...args) gets transformed.

Output with babel --plugins transform-class-properties,transform-es2015-parameters,transform-es2015-spread:

class SomeError extends Error {
  constructor() {
    var _temp;

    return _temp = super(...arguments), this.name = 'SomeError', _temp;
  }

}

throw new (Function.prototype.bind.apply(SomeError, [null].concat(['arguments'])))();

The transform-es2015-parameters could transform the constructor, but transform-es2015-spread still doesn't try to fix the ...arguments :(

Now for the big one.
Output with babel --plugins transform-class-properties,transform-es2015-classes,transform-es2015-parameters,transform-es2015-spread:

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }

function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

let SomeError = function (_Error) {
  _inherits(SomeError, _Error);

  function SomeError() {
    var _Object$getPrototypeO;

    var _temp, _this, _ret;

    _classCallCheck(this, SomeError);
    
    for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
      args[_key] = arguments[_key];
    }

    return _ret = (_temp = (_this = _possibleConstructorReturn(this, (_Object$getPrototypeO = Object.getPrototypeOf(SomeError)).call.apply(_Object$getPrototypeO, [this].concat(args))), _this), _this.name = 'SomeError', _temp), _possibleConstructorReturn(_this, _ret);


  }

  return SomeError;
}(Error);

function withSpread() {
  for (var _len2 = arguments.length, args = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
    args[_key2] = arguments[_key2];
  }

  throw new (Function.prototype.bind.apply(SomeError, [null].concat(args)))();
}

withSpread(1, 2);

The ordering was also important when adding the transform-es2015-classes. Putting it before transform-class-properties made it complain about the Missing class properties transform.

This is still current as of babel-plugin-transform-es2015-spread@6.8.0 and babel-plugin-transform-class-properties@6.10.2.

@tianjianchn
Copy link

Any update for this?

@nicolo-ribaudo
Copy link
Member

Any idea about how this could be fixed? I don't think that it is possible.

@github-actions github-actions bot added the outdated A closed issue/PR that is archived due to age. Recommended to make a new issue label May 4, 2021
@github-actions github-actions bot locked as resolved and limited conversation to collaborators May 4, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
help wanted outdated A closed issue/PR that is archived due to age. Recommended to make a new issue
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants