<p dir="auto">When compiling the following code: (the function <code class="notranslate">call</code> takes a 0-argument function and returns its result)</p>
<div class="highlight highlight-source-ts notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="type NoArgsFn&lt;T&gt; = () =&gt; T;

function call&lt;T, Fn extends NoArgsFn&lt;T&gt;&gt;(fn: Fn): T {
  return fn();
}

let result: number = call(() =&gt; 1);"><pre class="notranslate"><span class="pl-k">type</span> <span class="pl-smi">NoArgsFn</span><span class="pl-c1">&lt;</span><span class="pl-smi">T</span><span class="pl-c1">&gt;</span> <span class="pl-c1">=</span> <span class="pl-kos">(</span><span class="pl-kos">)</span> <span class="pl-c1">=&gt;</span> <span class="pl-smi">T</span><span class="pl-kos">;</span>

<span class="pl-k">function</span> <span class="pl-en">call</span><span class="pl-c1">&lt;</span><span class="pl-smi">T</span><span class="pl-kos">,</span> <span class="pl-smi">Fn</span> <span class="pl-k">extends</span> <span class="pl-smi">NoArgsFn</span><span class="pl-kos">&lt;</span><span class="pl-smi">T</span><span class="pl-kos">&gt;</span><span class="pl-c1">&gt;</span><span class="pl-kos">(</span><span class="pl-s1">fn</span>: <span class="pl-smi">Fn</span><span class="pl-kos">)</span>: <span class="pl-smi">T</span> <span class="pl-kos">{</span>
  <span class="pl-k">return</span> <span class="pl-en">fn</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">let</span> <span class="pl-s1">result</span>: <span class="pl-smi">number</span> <span class="pl-c1">=</span> <span class="pl-en">call</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-c1">1</span><span class="pl-kos">)</span><span class="pl-kos">;</span></pre></div>
<p dir="auto">I get the following incorrect error: (on the last line)</p>
<p dir="auto"><code class="notranslate">try.ts(7,5): error TS2322: Type '{}' is not assignable to type 'number'.</code></p>
<p dir="auto">The following workaround, adding an unused dummy argument of type T to the function, avoids this error:</p>
<div class="highlight highlight-source-ts notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="type NoArgsFn&lt;T&gt; = () =&gt; T;

function call&lt;T, Fn extends NoArgsFn&lt;T&gt;&gt;(fn: Fn, dummy: T): T {
  return fn();
}

let result: number = call(() =&gt; 1, -1);"><pre class="notranslate"><span class="pl-k">type</span> <span class="pl-smi">NoArgsFn</span><span class="pl-c1">&lt;</span><span class="pl-smi">T</span><span class="pl-c1">&gt;</span> <span class="pl-c1">=</span> <span class="pl-kos">(</span><span class="pl-kos">)</span> <span class="pl-c1">=&gt;</span> <span class="pl-smi">T</span><span class="pl-kos">;</span>

<span class="pl-k">function</span> <span class="pl-en">call</span><span class="pl-c1">&lt;</span><span class="pl-smi">T</span><span class="pl-kos">,</span> <span class="pl-smi">Fn</span> <span class="pl-k">extends</span> <span class="pl-smi">NoArgsFn</span><span class="pl-kos">&lt;</span><span class="pl-smi">T</span><span class="pl-kos">&gt;</span><span class="pl-c1">&gt;</span><span class="pl-kos">(</span><span class="pl-s1">fn</span>: <span class="pl-smi">Fn</span><span class="pl-kos">,</span> <span class="pl-s1">dummy</span>: <span class="pl-smi">T</span><span class="pl-kos">)</span>: <span class="pl-smi">T</span> <span class="pl-kos">{</span>
  <span class="pl-k">return</span> <span class="pl-en">fn</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">let</span> <span class="pl-s1">result</span>: <span class="pl-smi">number</span> <span class="pl-c1">=</span> <span class="pl-en">call</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-c1">1</span><span class="pl-kos">,</span> <span class="pl-c1">-</span><span class="pl-c1">1</span><span class="pl-kos">)</span><span class="pl-kos">;</span></pre></div>
<p dir="auto"><strong>TypeScript Version:</strong></p>
<p dir="auto">1.8.0</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="interface Class&lt;T&gt; {
    new(): T;
}
declare function create1&lt;T&gt;(ctor: Class&lt;T&gt;): T;
declare function create2&lt;T, C extends Class&lt;T&gt;&gt;(ctor: C): T;

class A {}
let a1 = create1(A); // a: A --&gt; OK
let a2 = create2(A); // a: {} --&gt; Should be A"><pre class="notranslate"><span class="pl-k">interface</span> <span class="pl-smi">Class</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-k">new</span><span class="pl-kos">(</span><span class="pl-kos">)</span>: <span class="pl-smi">T</span><span class="pl-kos">;</span>
<span class="pl-kos">}</span>
<span class="pl-k">declare</span> <span class="pl-k">function</span> <span class="pl-s1">create1</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">ctor</span>: <span class="pl-smi">Class</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-smi">T</span><span class="pl-kos">;</span>
<span class="pl-k">declare</span> <span class="pl-k">function</span> <span class="pl-s1">create2</span><span class="pl-c1">&lt;</span><span class="pl-smi">T</span><span class="pl-kos">,</span> <span class="pl-smi">C</span> <span class="pl-k">extends</span> <span class="pl-smi">Class</span><span class="pl-kos">&lt;</span><span class="pl-smi">T</span><span class="pl-kos">&gt;</span><span class="pl-c1">&gt;</span><span class="pl-kos">(</span><span class="pl-s1">ctor</span>: <span class="pl-smi">C</span><span class="pl-kos">)</span>: <span class="pl-smi">T</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-kos">}</span>
<span class="pl-k">let</span> <span class="pl-s1">a1</span> <span class="pl-c1">=</span> <span class="pl-en">create1</span><span class="pl-kos">(</span><span class="pl-smi">A</span><span class="pl-kos">)</span><span class="pl-kos">;</span> <span class="pl-c">// a: A --&gt; OK</span>
<span class="pl-k">let</span> <span class="pl-s1">a2</span> <span class="pl-c1">=</span> <span class="pl-en">create2</span><span class="pl-kos">(</span><span class="pl-smi">A</span><span class="pl-kos">)</span><span class="pl-kos">;</span> <span class="pl-c">// a: {} --&gt; Should be A</span></pre></div>
<p dir="auto"><strong>Context</strong></p>
<p dir="auto">The example above is simplified to illustrate the difference between <code class="notranslate">create1</code> and <code class="notranslate">create2</code>. I need both type parameters for the use case I have in mind (React) because it returns a type which is parameterized by both <code class="notranslate">T</code> and <code class="notranslate">C</code>:</p>
<div class="highlight highlight-source-ts notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="declare function createElement&lt;T, C extends Class&lt;T&gt;&gt;(type: C): Element&lt;T, C&gt;;
var e = createElement(A); // e: Element&lt;{}, typeof A&gt; --&gt; Should be Element&lt;A, typeof A&gt;

declare function render&lt;T&gt;(e: Element&lt;T, any&gt;): T;
var a = render(e); // a: {} --&gt; Should be A"><pre class="notranslate"><span class="pl-k">declare</span> <span class="pl-k">function</span> <span class="pl-s1">createElement</span><span class="pl-c1">&lt;</span><span class="pl-smi">T</span><span class="pl-kos">,</span> <span class="pl-smi">C</span> <span class="pl-k">extends</span> <span class="pl-smi">Class</span><span class="pl-kos">&lt;</span><span class="pl-smi">T</span><span class="pl-kos">&gt;</span><span class="pl-c1">&gt;</span><span class="pl-kos">(</span><span class="pl-s1">type</span>: <span class="pl-smi">C</span><span class="pl-kos">)</span>: <span class="pl-smi">Element</span><span class="pl-kos">&lt;</span><span class="pl-smi">T</span><span class="pl-kos">,</span> <span class="pl-smi">C</span><span class="pl-kos">&gt;</span><span class="pl-kos">;</span>
<span class="pl-k">var</span> <span class="pl-s1">e</span> <span class="pl-c1">=</span> <span class="pl-en">createElement</span><span class="pl-kos">(</span><span class="pl-smi">A</span><span class="pl-kos">)</span><span class="pl-kos">;</span> <span class="pl-c">// e: Element&lt;{}, typeof A&gt; --&gt; Should be Element&lt;A, typeof A&gt;</span>

<span class="pl-k">declare</span> <span class="pl-k">function</span> <span class="pl-s1">render</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">e</span>: <span class="pl-smi">Element</span><span class="pl-kos">&lt;</span><span class="pl-smi">T</span><span class="pl-kos">,</span> <span class="pl-smi">any</span><span class="pl-kos">&gt;</span><span class="pl-kos">)</span>: <span class="pl-smi">T</span><span class="pl-kos">;</span>
<span class="pl-k">var</span> <span class="pl-s1">a</span> <span class="pl-c1">=</span> <span class="pl-en">render</span><span class="pl-kos">(</span><span class="pl-s1">e</span><span class="pl-kos">)</span><span class="pl-kos">;</span> <span class="pl-c">// a: {} --&gt; Should be A</span></pre></div>
<p dir="auto">Again, this is simplified, but the motivation is to improve the return type inference of <code class="notranslate">ReactDOM.render</code>.</p>