Skip to content

Class is anonymous for decorator code #6420

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
TheLevenCreations opened this issue Jan 9, 2016 · 2 comments
Closed

Class is anonymous for decorator code #6420

TheLevenCreations opened this issue Jan 9, 2016 · 2 comments
Labels
Duplicate An existing issue was already created

Comments

@TheLevenCreations
Copy link

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);
@TheLevenCreations
Copy link
Author

btw, I am using tsc 1.7.5, target es6

@mhegazy
Copy link
Contributor

mhegazy commented Jan 14, 2016

looks like a duplicate of #5386

@mhegazy mhegazy closed this as completed Jan 14, 2016
@mhegazy mhegazy added the Duplicate An existing issue was already created label Jan 14, 2016
@microsoft microsoft locked and limited conversation to collaborators Jun 19, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Duplicate An existing issue was already created
Projects
None yet
Development

No branches or pull requests

2 participants