Skip to content

Decorated class gets name === "_a" when a #private field initializer references the class (regression in 7.0) #64494

Description

@bagbag

🔎 Search Terms

decorator class name _a, ES decorators private field class name, var Foo = _a = class, NamedEvaluation class name decorator, ClassDecoratorContext.name wrong, class .name regression 7.0, __esDecorate _classThis.name

🕗 Version & Regression Information

  • This changed between versions 6.0.3 and 7.0.1-rc. Also reproduces on 7.0.2 and 7.1.0-dev.20260926.1.

⏯ Playground Link

TS 7 doesn't work on Playground

💻 Code

function dec(_target: unknown, _context: ClassDecoratorContext): void {}

@dec
class Foo {
  #self = Foo;
}

console.log(Foo.name);

No compiler options are needed: tsc with { "files": ["a.ts"] } (default target), then node a.js.

🙁 Actual behavior

Prints _a. 7.0 emits the class expression through a chained assignment to the temporary _a:

let Foo = (() => {
    var _a;
    let _classDecorators = [dec];
    let _classDescriptor;
    let _classExtraInitializers = [];
    let _classThis;
    var Foo = _a = class {
        static { _classThis = this; }
        static {
            const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(null) : void 0;
            __esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
            Foo = _classThis = _classDescriptor.value;
            if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
            __runInitializers(_classThis, _classExtraInitializers);
        }
        #self = Foo;
    };
    return Foo = _classThis;
})();

The anonymous class is the right-hand side of _a = …, so NamedEvaluation names it _a. Foo.name is "_a". So is ClassDecoratorContext.name, because the decorator context is built from _classThis.name. _a is never read afterwards.

🙂 Expected behavior

Prints Foo, as 6.0.3 does. 6.0.3's emit differs only in this line:

-    var Foo = _a = class {
+    var Foo = class {

The emitted class's name, and the decorator context's name, should be the declared class name.

Additional information about the issue

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions