Skip to content

declare on computed class field with decorator makes invalid code that crashes due to missing _a #46345

Closed
@evanw

Description

@evanw

Bug Report

🔎 Search Terms

decorator declare computed class field symbol

🕗 Version & Regression Information

  • This is the behavior in every version I tried after the ability to add declare to class fields was introduced (so TypeScript 3.7+)

⏯ Playground Link

Playground link with relevant code

💻 Code

function dec(klass: any, name: any) {
  console.log(name)
}
const isSymbol = Symbol('isSymbol')
class Foo {
  @dec declare notSymbol: number;
  @dec declare [isSymbol]: number;
}

The context for this is that I recently became aware of the ability to add a decorator to a declare class field and I'm currently working on adding this feature to esbuild's TypeScript-to-JavaScript transformer, which doesn't currently support this feature. I discovered this bug in TypeScript while doing some reverse-engineering to figure out how the feature is supposed to work. See also evanw/esbuild#1675.

🙁 Actual behavior

The code crashes when run with Uncaught ReferenceError: _a is not defined. This is because the TypeScript compiler transforms the input code into this:

function dec(klass, name) {
    console.log(name);
}
const isSymbol = Symbol('isSymbol');
class Foo {
}
__decorate([
    dec
], Foo.prototype, "notSymbol", void 0);
__decorate([
    dec
], Foo.prototype, _a, void 0);

Notice how the declaration for the temporary variable _a was never actually generated.

🙂 Expected behavior

The code should print notSymbol followed by Symbol(isSymbol). Presumably the generated code would need to look something like this:

+var _a;
 function dec(klass, name) {
     console.log(name);
 }
 const isSymbol = Symbol('isSymbol');
 class Foo {
 }
+_a = isSymbol;
 __decorate([
     dec
 ], Foo.prototype, "notSymbol", void 0);
 __decorate([
     dec
 ], Foo.prototype, _a, void 0);

Metadata

Metadata

Assignees

No one assigned

    Labels

    BugA bug in TypeScriptDomain: JS EmitThe issue relates to the emission of JavaScript

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions