<p dir="auto">As an Javascript developer, I tried to implement the dependency injection, by using the tool introduced in rbuckton/ReflectDecorators (<a href="https://github.com/rbuckton/ReflectDecorators.git">https://github.com/rbuckton/ReflectDecorators.git</a>). However, I just found the following code will be compiled into an anonymous class declaration in js file.</p>
<div class="highlight highlight-source-ts notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="    @log
    class A {
        constructor() {
            Debug.log('A created');
        }

        afunc() {}

        bfunc() {}

    }"><pre class="notranslate">    @<span class="pl-s1">log</span>
    <span class="pl-k">class</span> <span class="pl-smi">A</span> <span class="pl-kos">{</span>
        <span class="pl-en">constructor</span><span class="pl-kos">(</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
            <span class="pl-smi">Debug</span><span class="pl-kos">.</span><span class="pl-en">log</span><span class="pl-kos">(</span><span class="pl-s">'A created'</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
        <span class="pl-kos">}</span>

        <span class="pl-en">afunc</span><span class="pl-kos">(</span><span class="pl-kos">)</span> <span class="pl-kos">{</span><span class="pl-kos">}</span>

        <span class="pl-en">bfunc</span><span class="pl-kos">(</span><span class="pl-kos">)</span> <span class="pl-kos">{</span><span class="pl-kos">}</span>

    <span class="pl-kos">}</span></pre></div>
<p dir="auto">The decorator <a class="user-mention notranslate" data-hovercard-type="organization" data-hovercard-url="/orgs/log/hovercard" data-octo-click="hovercard-link-click" data-octo-dimensions="link_type:self" href="https://github.com/log">@log</a> is quite simple, it is to print the class name.</p>
<div class="highlight highlight-source-ts notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="// class decorator
function log(target: any) {
    console.log(target.name);
    ....
}"><pre class="notranslate"><span class="pl-c">// class decorator</span>
<span class="pl-k">function</span> <span class="pl-en">log</span><span class="pl-kos">(</span><span class="pl-s1">target</span>: <span class="pl-smi">any</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
    <span class="pl-smi">console</span><span class="pl-kos">.</span><span class="pl-en">log</span><span class="pl-kos">(</span><span class="pl-s1">target</span><span class="pl-kos">.</span><span class="pl-c1">name</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
    ...<span class="pl-kos">.</span>
<span class="pl-kos">}</span></pre></div>
<p dir="auto">The generated javascript is as follows. I turned "emitDecoratorMetadata" to true in tsconfig.json</p>
<div class="highlight highlight-source-js notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="        let A = class {
            constructor() {
                Debug_1.Debug.log('A created');
            }
            afunc() { }
            bfunc() { }
        };
        A = __decorate([
            decorators_1.log, 
            __metadata('design:paramtypes', [])
        ], A);"><pre class="notranslate">        <span class="pl-k">let</span> <span class="pl-v">A</span> <span class="pl-c1">=</span> <span class="pl-k">class</span> <span class="pl-kos">{</span>
            <span class="pl-en">constructor</span><span class="pl-kos">(</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
                <span class="pl-v">Debug_1</span><span class="pl-kos">.</span><span class="pl-c1">Debug</span><span class="pl-kos">.</span><span class="pl-en">log</span><span class="pl-kos">(</span><span class="pl-s">'A created'</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
            <span class="pl-kos">}</span>
            <span class="pl-en">afunc</span><span class="pl-kos">(</span><span class="pl-kos">)</span> <span class="pl-kos">{</span> <span class="pl-kos">}</span>
            <span class="pl-en">bfunc</span><span class="pl-kos">(</span><span class="pl-kos">)</span> <span class="pl-kos">{</span> <span class="pl-kos">}</span>
        <span class="pl-kos">}</span><span class="pl-kos">;</span>
        <span class="pl-v">A</span> <span class="pl-c1">=</span> <span class="pl-en">__decorate</span><span class="pl-kos">(</span><span class="pl-kos">[</span>
            <span class="pl-s1">decorators_1</span><span class="pl-kos">.</span><span class="pl-c1">log</span><span class="pl-kos">,</span> 
            <span class="pl-en">__metadata</span><span class="pl-kos">(</span><span class="pl-s">'design:paramtypes'</span><span class="pl-kos">,</span> <span class="pl-kos">[</span><span class="pl-kos">]</span><span class="pl-kos">)</span>
        <span class="pl-kos">]</span><span class="pl-kos">,</span> <span class="pl-v">A</span><span class="pl-kos">)</span><span class="pl-kos">;</span></pre></div>
<p dir="auto">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.</p>
<p dir="auto">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:</p>
<div class="highlight highlight-source-ts notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="    @logClass('A')
    class A {
        constructor() {
            Debug.log('A created');
        }

        afunc() {}

        bfunc() {}

    }"><pre class="notranslate">    @<span class="pl-en">logClass</span><span class="pl-kos">(</span><span class="pl-s">'A'</span><span class="pl-kos">)</span>
    <span class="pl-k">class</span> <span class="pl-smi">A</span> <span class="pl-kos">{</span>
        <span class="pl-en">constructor</span><span class="pl-kos">(</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
            <span class="pl-smi">Debug</span><span class="pl-kos">.</span><span class="pl-en">log</span><span class="pl-kos">(</span><span class="pl-s">'A created'</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
        <span class="pl-kos">}</span>

        <span class="pl-en">afunc</span><span class="pl-kos">(</span><span class="pl-kos">)</span> <span class="pl-kos">{</span><span class="pl-kos">}</span>

        <span class="pl-en">bfunc</span><span class="pl-kos">(</span><span class="pl-kos">)</span> <span class="pl-kos">{</span><span class="pl-kos">}</span>

    <span class="pl-kos">}</span></pre></div>
<p dir="auto">After investigation in sources of Typescript, I found the following lines related to this issue:<br>
in function emitClassLikeDeclarationForES6AndHigher(node), it reads:</p>
<div class="highlight highlight-source-js notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="                ...
                write(&quot;class&quot;);
                if ((node.name || (node.flags &amp; 1024 &amp;&amp; staticProperties.length &gt; 0)) &amp;&amp; !thisNodeIsDecorated) {
                    write(&quot; &quot;);
                    emitDeclarationName(node);
                }"><pre class="notranslate">                ...
                <span class="pl-en">write</span><span class="pl-kos">(</span><span class="pl-s">"class"</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
                <span class="pl-k">if</span> <span class="pl-kos">(</span><span class="pl-kos">(</span><span class="pl-s1">node</span><span class="pl-kos">.</span><span class="pl-c1">name</span> <span class="pl-c1">||</span> <span class="pl-kos">(</span><span class="pl-s1">node</span><span class="pl-kos">.</span><span class="pl-c1">flags</span> <span class="pl-c1">&amp;</span> <span class="pl-c1">1024</span> <span class="pl-c1">&amp;&amp;</span> <span class="pl-s1">staticProperties</span><span class="pl-kos">.</span><span class="pl-c1">length</span> <span class="pl-c1">&gt;</span> <span class="pl-c1">0</span><span class="pl-kos">)</span><span class="pl-kos">)</span> <span class="pl-c1">&amp;&amp;</span> <span class="pl-c1">!</span><span class="pl-s1">thisNodeIsDecorated</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
                    <span class="pl-en">write</span><span class="pl-kos">(</span><span class="pl-s">" "</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
                    <span class="pl-en">emitDeclarationName</span><span class="pl-kos">(</span><span class="pl-s1">node</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
                <span class="pl-kos">}</span></pre></div>
<p dir="auto">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.</p>
<div class="highlight highlight-source-js notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="        let A = class A {
            constructor() {
                Debug_1.Debug.log('A created');
            }
            afunc() { }
            bfunc() { }
        };
        A = __decorate([
            decorators_1.log, 
            __metadata('design:paramtypes', [])
        ], A);
"><pre class="notranslate">        <span class="pl-k">let</span> <span class="pl-v">A</span> <span class="pl-c1">=</span> <span class="pl-k">class</span> <span class="pl-v">A</span> <span class="pl-kos">{</span>
            <span class="pl-en">constructor</span><span class="pl-kos">(</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
                <span class="pl-v">Debug_1</span><span class="pl-kos">.</span><span class="pl-c1">Debug</span><span class="pl-kos">.</span><span class="pl-en">log</span><span class="pl-kos">(</span><span class="pl-s">'A created'</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
            <span class="pl-kos">}</span>
            <span class="pl-en">afunc</span><span class="pl-kos">(</span><span class="pl-kos">)</span> <span class="pl-kos">{</span> <span class="pl-kos">}</span>
            <span class="pl-en">bfunc</span><span class="pl-kos">(</span><span class="pl-kos">)</span> <span class="pl-kos">{</span> <span class="pl-kos">}</span>
        <span class="pl-kos">}</span><span class="pl-kos">;</span>
        <span class="pl-v">A</span> <span class="pl-c1">=</span> <span class="pl-en">__decorate</span><span class="pl-kos">(</span><span class="pl-kos">[</span>
            <span class="pl-s1">decorators_1</span><span class="pl-kos">.</span><span class="pl-c1">log</span><span class="pl-kos">,</span> 
            <span class="pl-en">__metadata</span><span class="pl-kos">(</span><span class="pl-s">'design:paramtypes'</span><span class="pl-kos">,</span> <span class="pl-kos">[</span><span class="pl-kos">]</span><span class="pl-kos">)</span>
        <span class="pl-kos">]</span><span class="pl-kos">,</span> <span class="pl-v">A</span><span class="pl-kos">)</span><span class="pl-kos">;</span></pre></div>
<p dir="auto">I have decorator:</p>
<div class="highlight highlight-source-ts notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="export function Document() {
   return function(objectConstructor: Function) {
        console.log(objectConstructor.name); // when targeting es5 it gives me what I want - the name of my class. When targeting es6 it does not give anything
    }
}"><pre class="notranslate"><span class="pl-k">export</span> <span class="pl-k">function</span> <span class="pl-smi">Document</span><span class="pl-kos">(</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
   <span class="pl-k">return</span> <span class="pl-k">function</span><span class="pl-kos">(</span><span class="pl-s1">objectConstructor</span>: <span class="pl-smi">Function</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
        <span class="pl-smi">console</span><span class="pl-kos">.</span><span class="pl-en">log</span><span class="pl-kos">(</span><span class="pl-s1">objectConstructor</span><span class="pl-kos">.</span><span class="pl-c1">name</span><span class="pl-kos">)</span><span class="pl-kos">;</span> <span class="pl-c">// when targeting es5 it gives me what I want - the name of my class. When targeting es6 it does not give anything</span>
    <span class="pl-kos">}</span>
<span class="pl-kos">}</span></pre></div>
<p dir="auto">Here is decorator usage:</p>
<div class="highlight highlight-source-ts notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="@Document()
export class User {
}"><pre class="notranslate">@<span class="pl-smi">Document</span><span class="pl-kos">(</span><span class="pl-kos">)</span>
<span class="pl-k">export</span> <span class="pl-k">class</span> <span class="pl-smi">User</span> <span class="pl-kos">{</span>
<span class="pl-kos">}</span></pre></div>
<p dir="auto">Im using "User" class name to create a document called "User", I need information how class is called. I always used es5, but now when I switched to es6 compile target I dont have information about class name anymore. Is it a bug, or it by design? If second then what is the way to get the class name?</p>