<div class="highlight highlight-source-ts notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="// file: foo.ts
import BluebirdPromise from 'bluebird';
export async function foo(): BluebirdPromise { }

// file: foo.js
function foo() {
    return __awaiter(this, void 0, BluebirdPromise, function* () { });
}
exports.foo = foo;"><pre class="notranslate"><span class="pl-c">// file: foo.ts</span>
<span class="pl-k">import</span> <span class="pl-smi">BluebirdPromise</span> <span class="pl-k">from</span> <span class="pl-s">'bluebird'</span><span class="pl-kos">;</span>
<span class="pl-k">export</span> <span class="pl-k">async</span> <span class="pl-k">function</span> <span class="pl-en">foo</span><span class="pl-kos">(</span><span class="pl-kos">)</span>: <span class="pl-smi">BluebirdPromise</span> <span class="pl-kos">{</span> <span class="pl-kos">}</span>

<span class="pl-c">// file: foo.js</span>
<span class="pl-k">function</span> <span class="pl-en">foo</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-en">__awaiter</span><span class="pl-kos">(</span><span class="pl-smi">this</span><span class="pl-kos">,</span> <span class="pl-k">void</span> <span class="pl-c1">0</span><span class="pl-kos">,</span> <span class="pl-smi">BluebirdPromise</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-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
<span class="pl-kos">}</span>
<span class="pl-s1">exports</span><span class="pl-kos">.</span><span class="pl-c1">foo</span> <span class="pl-c1">=</span> <span class="pl-s1">foo</span><span class="pl-kos">;</span></pre></div>
<p dir="auto">(Compiled with <code class="notranslate">target=ES6, module=commonjs, noEmitHelpers=true</code>).</p>
<p dir="auto">The <code class="notranslate">BluebirdPromise</code> import has been elided in the generated code, resulting in <code class="notranslate">"ReferenceError: BluebirdPromise is not defined"</code> at runtime.</p>
<p dir="auto">The elision occurs because <code class="notranslate">BluebirdPromise</code> only appears in a type position which up until v1.7 meant that the compiler could safely elide it. But the compiler now emits this type annotation into the JavaScript output so that elision assumption is no longer safe.</p>
<p dir="auto">IMO the problem here is not the elision logic, its the fact that the compiler now emits code that depends on type annotaitons, so the type system no longer enjoys the quality of being fully erasable, which I understood to be a core <a href="https://github.com/Microsoft/TypeScript/wiki/TypeScript-Design-Goals#goals">design principle</a> of the language. I thought the idea of using type annotations to change runtime behaviour would have been smacked down by <a class="user-mention notranslate" data-hovercard-type="user" data-hovercard-url="/users/ahejlsberg/hovercard" data-octo-click="hovercard-link-click" data-octo-dimensions="link_type:self" href="https://github.com/ahejlsberg">@ahejlsberg</a> and the team before it got into production.</p>
<p dir="auto">Regardless of that contended side-topic, I believe this is a bug.</p>
<p dir="auto">The generated JS code is missing a dependency onto the references promise implementation. Steps to reproduce:</p>
<ul dir="auto">
<li>install bluebird promises</li>
<li>create the following bluebird.d.ts.</li>
</ul>
<div class="highlight highlight-source-ts notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="declare module 'bluebird' {
    interface Promise&lt;T&gt; {
        then&lt;U&gt;(onFulfilled: (value: T) =&gt; U, onRejected: (reason: any) =&gt; U): Promise&lt;T&gt;;
    }

    var Promise: {
        new&lt;T&gt;(resolver: (resolve: (value: T) =&gt; void, reject: (reason: any) =&gt; void) =&gt; void): Promise&lt;T&gt;;
    }   
}"><pre class="notranslate"><span class="pl-k">declare</span> module <span class="pl-s">'bluebird'</span> <span class="pl-kos">{</span>
    <span class="pl-k">interface</span> <span class="pl-smi">Promise</span><span class="pl-c1">&lt;</span><span class="pl-smi">T</span><span class="pl-c1">&gt;</span> <span class="pl-kos">{</span>
        <span class="pl-c1">then</span><span class="pl-c1">&lt;</span><span class="pl-smi">U</span><span class="pl-c1">&gt;</span><span class="pl-kos">(</span><span class="pl-s1">onFulfilled</span>: <span class="pl-kos">(</span><span class="pl-s1">value</span>: <span class="pl-smi">T</span><span class="pl-kos">)</span> <span class="pl-c1">=&gt;</span> <span class="pl-smi">U</span><span class="pl-kos">,</span> <span class="pl-s1">onRejected</span>: <span class="pl-kos">(</span><span class="pl-s1">reason</span>: <span class="pl-smi">any</span><span class="pl-kos">)</span> <span class="pl-c1">=&gt;</span> <span class="pl-smi">U</span><span class="pl-kos">)</span>: <span class="pl-smi">Promise</span><span class="pl-kos">&lt;</span><span class="pl-smi">T</span><span class="pl-kos">&gt;</span><span class="pl-kos">;</span>
    <span class="pl-kos">}</span>

    <span class="pl-k">var</span> <span class="pl-smi">Promise</span>: <span class="pl-kos">{</span>
        <span class="pl-k">new</span><span class="pl-c1">&lt;</span><span class="pl-smi">T</span><span class="pl-c1">&gt;</span><span class="pl-kos">(</span><span class="pl-s1">resolver</span>: <span class="pl-kos">(</span><span class="pl-s1">resolve</span>: <span class="pl-kos">(</span><span class="pl-s1">value</span>: <span class="pl-smi">T</span><span class="pl-kos">)</span> <span class="pl-c1">=&gt;</span> <span class="pl-smi"><span class="pl-k">void</span></span><span class="pl-kos">,</span> <span class="pl-s1">reject</span>: <span class="pl-kos">(</span><span class="pl-s1">reason</span>: <span class="pl-smi">any</span><span class="pl-kos">)</span> <span class="pl-c1">=&gt;</span> <span class="pl-smi"><span class="pl-k">void</span></span><span class="pl-kos">)</span> <span class="pl-c1">=&gt;</span> <span class="pl-smi"><span class="pl-k">void</span></span><span class="pl-kos">)</span>: <span class="pl-smi">Promise</span><span class="pl-kos">&lt;</span><span class="pl-smi">T</span><span class="pl-kos">&gt;</span><span class="pl-kos">;</span>
    <span class="pl-kos">}</span>   
<span class="pl-kos">}</span></pre></div>
<ul dir="auto">
<li>create a test file</li>
</ul>
<div class="highlight highlight-source-ts notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="import * as bluebird from 'bluebird';

async function firstName(): bluebird.Promise&lt;string&gt;  {
    return &quot;Dirk&quot;;
}

async function lastName(): Promise&lt;string&gt; {
    return &quot;Baeumer&quot;;
}

async function use() {
    var first = await firstName();
    var last = await lastName();
    return `${first} ${last}`;
}

if (require.main === module) {
    var p = use();
    p.then((value) =&gt; console.log(value));
}"><pre class="notranslate"><span class="pl-k">import</span> <span class="pl-c1">*</span> <span class="pl-k">as</span> <span class="pl-s1">bluebird</span> <span class="pl-k">from</span> <span class="pl-s">'bluebird'</span><span class="pl-kos">;</span>

<span class="pl-k">async</span> <span class="pl-k">function</span> <span class="pl-en">firstName</span><span class="pl-kos">(</span><span class="pl-kos">)</span>: <span class="pl-s1">bluebird</span><span class="pl-kos">.</span><span class="pl-smi">Promise</span><span class="pl-kos">&lt;</span><span class="pl-smi">string</span><span class="pl-kos">&gt;</span>  <span class="pl-kos">{</span>
    <span class="pl-k">return</span> <span class="pl-s">"Dirk"</span><span class="pl-kos">;</span>
<span class="pl-kos">}</span>

<span class="pl-k">async</span> <span class="pl-k">function</span> <span class="pl-en">lastName</span><span class="pl-kos">(</span><span class="pl-kos">)</span>: <span class="pl-smi">Promise</span><span class="pl-kos">&lt;</span><span class="pl-smi">string</span><span class="pl-kos">&gt;</span> <span class="pl-kos">{</span>
    <span class="pl-k">return</span> <span class="pl-s">"Baeumer"</span><span class="pl-kos">;</span>
<span class="pl-kos">}</span>

<span class="pl-k">async</span> <span class="pl-k">function</span> <span class="pl-en">use</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-s1">first</span> <span class="pl-c1">=</span> <span class="pl-k">await</span> <span class="pl-en">firstName</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-s1">last</span> <span class="pl-c1">=</span> <span class="pl-k">await</span> <span class="pl-en">lastName</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-s">`<span class="pl-s1"><span class="pl-kos">${</span><span class="pl-s1">first</span><span class="pl-kos">}</span></span> <span class="pl-s1"><span class="pl-kos">${</span><span class="pl-s1">last</span><span class="pl-kos">}</span></span>`</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-en">require</span><span class="pl-kos">.</span><span class="pl-c1">main</span> <span class="pl-c1">===</span> <span class="pl-smi">module</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
    <span class="pl-k">var</span> <span class="pl-s1">p</span> <span class="pl-c1">=</span> <span class="pl-en">use</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
    <span class="pl-s1">p</span><span class="pl-kos">.</span><span class="pl-en">then</span><span class="pl-kos">(</span><span class="pl-kos">(</span><span class="pl-s1">value</span><span class="pl-kos">)</span> <span class="pl-c1">=&gt;</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">value</span><span class="pl-kos">)</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
<span class="pl-kos">}</span></pre></div>
<ul dir="auto">
<li>compile and run.</li>
</ul>
<p dir="auto">Observe: you get an exception. Problem is that the generated code is missing a</p>
<div class="highlight highlight-source-ts notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="var  bluebird = require('bluebird');"><pre class="notranslate"><span class="pl-k">var</span>  <span class="pl-s1">bluebird</span> <span class="pl-c1">=</span> <span class="pl-en">require</span><span class="pl-kos">(</span><span class="pl-s">'bluebird'</span><span class="pl-kos">)</span><span class="pl-kos">;</span></pre></div>
<p dir="auto">statement.</p>