Description
As an Javascript developer, I tried to implement the dependency injection, by using the tool introduced in rbuckton/ReflectDecorators (https://github.com/rbuckton/ReflectDecorators.git). However, I just found the following code will be compiled into an anonymous class declaration in js file.
@log
class A {
constructor() {
Debug.log('A created');
}
afunc() {}
bfunc() {}
}
The decorator @log is quite simple, it is to print the class name.
// class decorator
function log(target: any) {
console.log(target.name);
....
}
The generated javascript is as follows. I turned "emitDecoratorMetadata" to true in tsconfig.json
let A = class {
constructor() {
Debug_1.Debug.log('A created');
}
afunc() { }
bfunc() { }
};
A = __decorate([
decorators_1.log,
__metadata('design:paramtypes', [])
], A);
I am so frustrated to see that constructor A is actually a class without name - the target in decorator code is an actually anonymous constructor function.
I do not know why. I can not figure out why make it anonymous if one decorator is there. As a result, I have to implement it like the following, which looks really odd and confusing, by using metadata Reflect API:
@logClass('A')
class A {
constructor() {
Debug.log('A created');
}
afunc() {}
bfunc() {}
}
After investigation in sources of Typescript, I found the following lines related to this issue:
in function emitClassLikeDeclarationForES6AndHigher(node), it reads:
...
write("class");
if ((node.name || (node.flags & 1024 && staticProperties.length > 0)) && !thisNodeIsDecorated) {
write(" ");
emitDeclarationName(node);
}
So while compiling class A, thisNodeIsDecorated is true and the name is never emitted. May I ask why? Would it better to just emit class name, like the following? Please let me know, if I missed something. Thanks very much.
let A = class A {
constructor() {
Debug_1.Debug.log('A created');
}
afunc() { }
bfunc() { }
};
A = __decorate([
decorators_1.log,
__metadata('design:paramtypes', [])
], A);