Esbuild: SyntaxError: 'super' keyword unexpected here

Created on 8 Sep 2020  路  3Comments  路  Source: evanw/esbuild

Hi @evanw

First of all thank you for such an amazing project!

I was trying to use esbuild with my existing typescript codebase but I encountered an error with super keyword

To reproduce the issue:

create a test.ts file

class Base {
  async create() {
    console.log("Base create");
  }
}
class Hello extends Base {
  async create() {
    console.log("Hello Create");
    super.create();
  }
}

console.log(new Hello().create());

Now run esbuild on it with

esbuild test.ts --target=es2015 --outdir=./build

Now try to run node ./build/test.js. You would get

      super.create();
      ^^^^^

SyntaxError: 'super' keyword unexpected here

I believe this is happening since

transpiled build/test.js looks like this

var __async = (__this, __arguments, generator) => {
  return new Promise((resolve, reject) => {
    var fulfilled = (value) => {
      try {
        step(generator.next(value));
      } catch (e) {
        reject(e);
      }
    };
    var rejected = (value) => {
      try {
        step(generator.throw(value));
      } catch (e) {
        reject(e);
      }
    };
    var step = (result) => {
      return result.done ? resolve(result.value) : Promise.resolve(result.value).then(fulfilled, rejected);
    };
    step((generator = generator.apply(__this, __arguments)).next());
  });
};
class Base {
  create() {
    return __async(this, null, function* () {
      console.log("Base create");
    });
  }
}
class Hello extends Base {
  create() {
    return __async(this, null, function* () {
      console.log("Hello Create");
      super.create();
    });
  }
}
console.log(new Hello().create());

and it breaks because the generator function of __async wrapper is not a member function ?

Most helpful comment

The fix was just released in version 0.6.33.

All 3 comments

Babel handles this by creating hoisted super property getter functions and then replacing super property access:

```js
class Hello extends Base {
async create() {
console.log("Hello Create");
super.create();
}
}

// is transformed into:

class Hello extends Base {
create() {
var _superprop_getCreate = () => super.create,
_this = this;

return _asyncToGenerator(function* () {
  console.log("Hello Create");

  _superprop_getCreate().call(_this);
})();

}
}

ESBuild doesn't currently lower arrow functions, so it could probably do something a bit simpler (not needing to handle context), for example:

 ```js
class Hello extends Base {
  create() {
    let _superprop_getCreate = () => super.create;

    return __async(this, null, function* () {
      console.log("Hello Create");
      _superprop_getCreate().call(this);
    });
  }
}

Yes, I'm planning to do something similar. I'm planning to use let helper = x => super[x] instead since that handles both the super.x and super[x] cases.

The fix was just released in version 0.6.33.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

iamakulov picture iamakulov  路  4Comments

qnp picture qnp  路  4Comments

OneOfOne picture OneOfOne  路  3Comments

evanplaice picture evanplaice  路  3Comments

mixtur picture mixtur  路  4Comments