ES `ClassDecoratorContext.name` has incorrect value with static `name`
🔎 Search Terms
ClassDecoratorContext static name
🕗 Version & Regression Information
5.0.4-5.9.3
⏯ Playground Link
https://tsplay.dev/N7vAow
💻 Code
const decorate = (_: unknown, ctx: ClassDecoratorContext) => {
console.log('decorate(%o)', ctx.name);
};
@decorate
class A {
static get name() {
return 2434;
}
}
🙁 Actual behavior
ctx.name is 2434 (from A.name)
🙂 Expected behavior
ctx.name is 'A' (actual class name)
Additional information about the issue
The wrong value comes from the context initializer in the emitted code:
__esDecorate(
null,
(_classDescriptor = { value: _classThis }),
_classDecorators,
{ kind: 'class', name: _classThis.name, metadata: _metadata },
null,
_classExtraInitializers,
);
The context name is initialized with _classThis.name (which triggers the getter) instead of the actual class name value (literal "A" in this case).
Possible Fix
Currently, the _classThis.name fragment comes from const classNameReference in transformClassLike in transformers/esDecorators.ts:
const classNameReference = factory.createPropertyAccessExpression(renamedClassThis, "name");
It should be adjusted to get an actual class name (either literal or computed), possibly like this:
const classNameReference = node.name ? factory.createStringLiteralFromNode(node.name) :
node.emitNode?.assignedName ?? factory.createStringLiteral("")
Hi @RyanCavanaugh !! Could I be assigned ??
The issue comes from using renamedClassThis.name, which invokes the user-defined getter. It should instead use the literal class name.
Happy to open a PR !!
Hello @RyanCavanaugh , I've submitted a fix for this issue!
The fix uses the literal class name instead of accessing _classThis.name, exactly as suggested in the issue. Added a test case covering static name getter, static name property, and normal class scenarios.
Thanks @miyaokamarina for the detailed issue and suggested fix, it made implementing this straightforward!