<p dir="auto"><strong>TypeScript Version:</strong></p>
<p dir="auto">1.8.10</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="// SubClass is declared before its SuperClass
class SubClass extends SuperClass {
}

class SuperClass {
}"><pre class="notranslate"><span class="pl-c">// SubClass is declared before its SuperClass</span>
<span class="pl-k">class</span> <span class="pl-smi">SubClass</span> <span class="pl-k">extends</span> <span class="pl-smi">SuperClass</span> <span class="pl-kos">{</span>
<span class="pl-kos">}</span>

<span class="pl-k">class</span> <span class="pl-smi">SuperClass</span> <span class="pl-kos">{</span>
<span class="pl-kos">}</span></pre></div>
<p dir="auto">generated code:</p>
<div class="highlight highlight-source-js notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="var __extends = (this &amp;&amp; this.__extends) || function (d, b) {
    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
    function __() { this.constructor = d; }
    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
var SubClass = (function (_super) {
    __extends(SubClass, _super);
    function SubClass() {
        _super.apply(this, arguments);
    }
    return SubClass;
}(SuperClass));
var SuperClass = (function () {
    function SuperClass() {
    }
    return SuperClass;
}());"><pre class="notranslate"><span class="pl-k">var</span> <span class="pl-s1">__extends</span> <span class="pl-c1">=</span> <span class="pl-kos">(</span><span class="pl-smi">this</span> <span class="pl-c1">&amp;&amp;</span> <span class="pl-smi">this</span><span class="pl-kos">.</span><span class="pl-c1">__extends</span><span class="pl-kos">)</span> <span class="pl-c1">||</span> <span class="pl-k">function</span> <span class="pl-kos">(</span><span class="pl-s1">d</span><span class="pl-kos">,</span> <span class="pl-s1">b</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
    <span class="pl-k">for</span> <span class="pl-kos">(</span><span class="pl-k">var</span> <span class="pl-s1">p</span> <span class="pl-k">in</span> <span class="pl-s1">b</span><span class="pl-kos">)</span> <span class="pl-k">if</span> <span class="pl-kos">(</span><span class="pl-s1">b</span><span class="pl-kos">.</span><span class="pl-en">hasOwnProperty</span><span class="pl-kos">(</span><span class="pl-s1">p</span><span class="pl-kos">)</span><span class="pl-kos">)</span> <span class="pl-s1">d</span><span class="pl-kos">[</span><span class="pl-s1">p</span><span class="pl-kos">]</span> <span class="pl-c1">=</span> <span class="pl-s1">b</span><span class="pl-kos">[</span><span class="pl-s1">p</span><span class="pl-kos">]</span><span class="pl-kos">;</span>
    <span class="pl-k">function</span> <span class="pl-c1">__</span><span class="pl-kos">(</span><span class="pl-kos">)</span> <span class="pl-kos">{</span> <span class="pl-smi">this</span><span class="pl-kos">.</span><span class="pl-c1">constructor</span> <span class="pl-c1">=</span> <span class="pl-s1">d</span><span class="pl-kos">;</span> <span class="pl-kos">}</span>
    <span class="pl-s1">d</span><span class="pl-kos">.</span><span class="pl-c1">prototype</span> <span class="pl-c1">=</span> <span class="pl-s1">b</span> <span class="pl-c1">===</span> <span class="pl-c1">null</span> ? <span class="pl-v">Object</span><span class="pl-kos">.</span><span class="pl-en">create</span><span class="pl-kos">(</span><span class="pl-s1">b</span><span class="pl-kos">)</span> : <span class="pl-kos">(</span><span class="pl-c1">__</span><span class="pl-kos">.</span><span class="pl-c1">prototype</span> <span class="pl-c1">=</span> <span class="pl-s1">b</span><span class="pl-kos">.</span><span class="pl-c1">prototype</span><span class="pl-kos">,</span> <span class="pl-k">new</span> <span class="pl-c1">__</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-k">var</span> <span class="pl-v">SubClass</span> <span class="pl-c1">=</span> <span class="pl-kos">(</span><span class="pl-k">function</span> <span class="pl-kos">(</span><span class="pl-s1">_super</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
    <span class="pl-s1">__extends</span><span class="pl-kos">(</span><span class="pl-v">SubClass</span><span class="pl-kos">,</span> <span class="pl-s1">_super</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
    <span class="pl-k">function</span> <span class="pl-v">SubClass</span><span class="pl-kos">(</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
        <span class="pl-s1">_super</span><span class="pl-kos">.</span><span class="pl-en">apply</span><span class="pl-kos">(</span><span class="pl-smi">this</span><span class="pl-kos">,</span> <span class="pl-smi">arguments</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-v">SubClass</span><span class="pl-kos">;</span>
<span class="pl-kos">}</span><span class="pl-kos">(</span><span class="pl-v">SuperClass</span><span class="pl-kos">)</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
<span class="pl-k">var</span> <span class="pl-v">SuperClass</span> <span class="pl-c1">=</span> <span class="pl-kos">(</span><span class="pl-k">function</span> <span class="pl-kos">(</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
    <span class="pl-k">function</span> <span class="pl-v">SuperClass</span><span class="pl-kos">(</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-v">SuperClass</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><br>
The order of class declarations in TypeScript should not be important. As evidence, the above code passes compilation and thus should not cause runtime error</p>
<p dir="auto">.</p>
<p dir="auto"><strong>Actual behavior:</strong><br>
Runtime error is thrown <code class="notranslate">Uncaught TypeError: Cannot read property 'prototype' of undefined</code> on line 4.</p>
<p dir="auto">The reason is that in the call to <code class="notranslate">__extends(SubClass, _super)</code> on line 7 the _super variable is undefined, but the __extends function checks for strict null (<code class="notranslate">b === null</code> on line 4) and thus fails on undefined.</p>
<p dir="auto">TS:</p>
<div class="highlight highlight-source-ts notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="class A extends B { }
class B { }
// no TS errors here"><pre class="notranslate"><span class="pl-k">class</span> <span class="pl-smi">A</span> <span class="pl-k">extends</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">// no TS errors here</span></pre></div>
<p dir="auto">JS:</p>
<div class="highlight highlight-source-js notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="var A = (function (_super) {
        __extends(A, _super);
        function A() {
            _super.apply(this, arguments);
        }
        return A;
    })(B);
var B = (function () {
        function B() {
        }
        return B;
    })();"><pre class="notranslate"><span class="pl-k">var</span> <span class="pl-v">A</span> <span class="pl-c1">=</span> <span class="pl-kos">(</span><span class="pl-k">function</span> <span class="pl-kos">(</span><span class="pl-s1">_super</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
        <span class="pl-en">__extends</span><span class="pl-kos">(</span><span class="pl-v">A</span><span class="pl-kos">,</span> <span class="pl-s1">_super</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
        <span class="pl-k">function</span> <span class="pl-v">A</span><span class="pl-kos">(</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
            <span class="pl-s1">_super</span><span class="pl-kos">.</span><span class="pl-en">apply</span><span class="pl-kos">(</span><span class="pl-smi">this</span><span class="pl-kos">,</span> <span class="pl-smi">arguments</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-v">A</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">B</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
<span class="pl-k">var</span> <span class="pl-v">B</span> <span class="pl-c1">=</span> <span class="pl-kos">(</span><span class="pl-k">function</span> <span class="pl-kos">(</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
        <span class="pl-k">function</span> <span class="pl-v">B</span><span class="pl-kos">(</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-v">B</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">When "__extends(A, _super);" is called "_super" is not defined yet and it's prototype, of course. I guess TS side should complain or JS should be reordered.</p>