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 ?
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.
Most helpful comment
The fix was just released in version 0.6.33.