Skip to content

Invalid transform of async arrow expression containing superΒ #46828

@evanw

Description

@evanw

Bug Report

πŸ”Ž Search Terms

super property setter getter method lowered async arrow function expression generator

πŸ•— Version & Regression Information

  • This is the behavior in every version I tried

⏯ Playground Link

Playground link with relevant code

πŸ’» Code

class Base {
  set setter(x: string) {}
  get getter() { return '' }
  method(x: string) {}

  static set setter(x: number) {}
  static get getter() { return 0 }
  static method(x: number) {}
}

class Derived extends Base {
  a() { return async () => super.method('') }
  b() { return async () => super.getter }
  c() { return async () => super.setter = '' }

  static a() { return async () => super.method(0) }
  static b() { return async () => super.getter }
  static c() { return async () => super.setter = 0 }
}

πŸ™ Actual behavior

Here's the above code compiled by TypeScript with a target of ES2015:

class Base {
    set setter(x) { }
    get getter() { return ''; }
    method(x) { }
    static set setter(x) { }
    static get getter() { return 0; }
    static method(x) { }
}
class Derived extends Base {
    a() { return () => __awaiter(this, void 0, void 0, function* () { return super.method(''); }); }
    b() { return () => __awaiter(this, void 0, void 0, function* () { return super.getter; }); }
    c() { return () => __awaiter(this, void 0, void 0, function* () { return super.setter = ''; }); }
    static a() { return () => __awaiter(this, void 0, void 0, function* () { return super.method(0); }); }
    static b() { return () => __awaiter(this, void 0, void 0, function* () { return super.getter; }); }
    static c() { return () => __awaiter(this, void 0, void 0, function* () { return super.setter = 0; }); }
}

The resulting code contains syntax errors:

Uncaught SyntaxError: 
    a() { return () => __awaiter(this, void 0, void 0, function* () { return super.method(''); }); }
                                                                             ^

'super' keyword outside a method

πŸ™‚ Expected behavior

I expected the uses of super inside async arrow expressions to be transformed into a helper function similarly to how TypeScript currently transforms super inside async methods. Perhaps TypeScript's output would look something like this instead:

class Base {
    set setter(x) { }
    get getter() { return ''; }
    method(x) { }
    static set setter(x) { }
    static get getter() { return 0; }
    static method(x) { }
}
class Derived extends Base {
    a() {
        const _super = Object.create(null, { method: { get: () => super.method } });
        return () => __awaiter(this, void 0, void 0, function* () { return _super.method.call(this, ''); });
    }
    b() {
        const _super = Object.create(null, { getter: { get: () => super.getter } });
        return () => __awaiter(this, void 0, void 0, function* () { return _super.getter; });
    }
    c() {
        const _super = Object.create(null, { setter: { get: () => super.setter, set: v => super.setter = v } });
        return () => __awaiter(this, void 0, void 0, function* () { return _super.setter = ''; });
    }
    static a() {
        const _super = Object.create(null, { method: { get: () => super.method } });
        return () => __awaiter(this, void 0, void 0, function* () { return _super.method.call(this, 0); });
    }
    static b() {
        const _super = Object.create(null, { getter: { get: () => super.getter } });
        return () => __awaiter(this, void 0, void 0, function* () { return _super.getter; });
    }
    static c() {
        const _super = Object.create(null, { setter: { get: () => super.setter, set: v => super.setter = v } });
        return () => __awaiter(this, void 0, void 0, function* () { return _super.setter = 0; });
    }
}

Metadata

Metadata

Assignees

Labels

BugA bug in TypeScriptFix AvailableA PR has been opened for this issueRescheduledThis issue was previously scheduled to an earlier milestone

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions