<p dir="auto"><strong>TypeScript Version:</strong></p>
<p dir="auto">1.8.7</p>
<p dir="auto"><strong>Code</strong></p>
<div class="highlight highlight-source-ts notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="import &quot;reflect-metadata&quot;;

function dec(target: Object, propertyKey: string) {
}

it(&quot;Check emitted design types&quot;, () =&gt; {
    class B {
    }

    class A {
        @dec
        b: B;
    }

    // Works as expected
    expect(Reflect.getMetadata(&quot;design:type&quot;, A.prototype, &quot;b&quot;)).toBeDefined();
});

it(&quot;Check emitted design types - reverse order&quot;, () =&gt; {
    class A {
        @dec
        b: B;
    }

    class B {
    }

    // Fails!!!
    expect(Reflect.getMetadata(&quot;design:type&quot;, A.prototype, &quot;b&quot;)).toBeDefined();
});"><pre class="notranslate"><span class="pl-k">import</span> <span class="pl-s">"reflect-metadata"</span><span class="pl-kos">;</span>

<span class="pl-k">function</span> <span class="pl-en">dec</span><span class="pl-kos">(</span><span class="pl-s1">target</span>: <span class="pl-smi">Object</span><span class="pl-kos">,</span> <span class="pl-s1">propertyKey</span>: <span class="pl-smi">string</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
<span class="pl-kos">}</span>

<span class="pl-en">it</span><span class="pl-kos">(</span><span class="pl-s">"Check emitted design types"</span><span class="pl-kos">,</span> <span class="pl-kos">(</span><span class="pl-kos">)</span> <span class="pl-c1">=&gt;</span> <span class="pl-kos">{</span>
    <span class="pl-k">class</span> <span class="pl-smi">B</span> <span class="pl-kos">{</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-s1">dec</span>
        <span class="pl-c1">b</span>: <span class="pl-smi">B</span><span class="pl-kos">;</span>
    <span class="pl-kos">}</span>

    <span class="pl-c">// Works as expected</span>
    <span class="pl-en">expect</span><span class="pl-kos">(</span><span class="pl-smi">Reflect</span><span class="pl-kos">.</span><span class="pl-en">getMetadata</span><span class="pl-kos">(</span><span class="pl-s">"design:type"</span><span class="pl-kos">,</span> <span class="pl-smi">A</span><span class="pl-kos">.</span><span class="pl-c1">prototype</span><span class="pl-kos">,</span> <span class="pl-s">"b"</span><span class="pl-kos">)</span><span class="pl-kos">)</span><span class="pl-kos">.</span><span class="pl-en">toBeDefined</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-en">it</span><span class="pl-kos">(</span><span class="pl-s">"Check emitted design types - reverse order"</span><span class="pl-kos">,</span> <span class="pl-kos">(</span><span class="pl-kos">)</span> <span class="pl-c1">=&gt;</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-s1">dec</span>
        <span class="pl-c1">b</span>: <span class="pl-smi">B</span><span class="pl-kos">;</span>
    <span class="pl-kos">}</span>

    <span class="pl-k">class</span> <span class="pl-smi">B</span> <span class="pl-kos">{</span>
    <span class="pl-kos">}</span>

    <span class="pl-c">// Fails!!!</span>
    <span class="pl-en">expect</span><span class="pl-kos">(</span><span class="pl-smi">Reflect</span><span class="pl-kos">.</span><span class="pl-en">getMetadata</span><span class="pl-kos">(</span><span class="pl-s">"design:type"</span><span class="pl-kos">,</span> <span class="pl-smi">A</span><span class="pl-kos">.</span><span class="pl-c1">prototype</span><span class="pl-kos">,</span> <span class="pl-s">"b"</span><span class="pl-kos">)</span><span class="pl-kos">)</span><span class="pl-kos">.</span><span class="pl-en">toBeDefined</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></pre></div>
<p dir="auto"><strong>Expected behavior:</strong> I'd expect design type metadata to be defined in both cases</p>
<p dir="auto"><strong>Actual behavior:</strong> Only first case works as expected</p>
<p dir="auto">I have the following code:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="@decorator
class A {
    constructor(param : B) {

    }
}

class B {

}

function decorator(target: any) {
    return target;
}

console.log(Reflect.getMetadata(&quot;design:paramtypes&quot;, A));"><pre class="notranslate"><code class="notranslate">@decorator
class A {
    constructor(param : B) {

    }
}

class B {

}

function decorator(target: any) {
    return target;
}

console.log(Reflect.getMetadata("design:paramtypes", A));
</code></pre></div>
<p dir="auto">The expected output should be: <code class="notranslate">[function B()]</code>, but the actual output is <code class="notranslate">[undefined]</code>. The issue is related to the definition order in the resulting js file, in which there is the following code:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="var A = (function () {
    function A(param) {
    }
    A = __decorate([
        decorator, 
        __metadata('design:paramtypes', [B])
    ], A);
    return A;
})();
var B = (function () {
    function B() {
    }
    return B;
})();"><pre class="notranslate"><code class="notranslate">var A = (function () {
    function A(param) {
    }
    A = __decorate([
        decorator, 
        __metadata('design:paramtypes', [B])
    ], A);
    return A;
})();
var B = (function () {
    function B() {
    }
    return B;
})();
</code></pre></div>
<p dir="auto">Since A is defined by a IIFE, in its execution scope B is not yet defined, so the generated metadata is incorrectly set to undefined. The only workaround I can use now is to declare B before A.</p>