Skip to content

Class is anonymous for decorator code #6420

Closed
@TheLevenCreations

Description

@TheLevenCreations

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);

Metadata

Metadata

Assignees

No one assigned

    Labels

    DuplicateAn existing issue was already created

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions