<p dir="auto"><strong>TypeScript Version:</strong></p>
<p dir="auto">1.9.0-dev / nightly (1.9.0-dev.20160311)</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="class ModelA&lt;T extends BaseData&gt;
{
    public prop : T;

    public constructor($prop : T) { }

    public Foo&lt;TData, TModel&gt;(
        $fn1 : ($x : T) =&gt; TData,
        $fn2 : ($x : TData) =&gt; TModel) { }

    public Foo1&lt;TData, TModel extends ModelA&lt;any&gt;&gt;(
        $fn1 : ($x : T) =&gt; TData,
        $fn2 : ($x : TData) =&gt; TModel) { }

    public Foo2&lt;TData extends BaseData, TModel extends ModelA&lt;TData&gt;&gt;(
        $fn1 : ($x : T) =&gt; TData,
        $fn2 : ($x : TData) =&gt; TModel) { }
}

class ModelB extends ModelA&lt;Data&gt; { }

class BaseData
{
    public a : string;
}

class Data extends BaseData
{
    public b : Data;
}

class P
{
    public static Run()
    {
        var modelA = new ModelA&lt;Data&gt;(new Data());

        modelA.Foo(x1 =&gt; x1.b, x2 =&gt; new ModelB(x2));

        modelA.Foo1(x1 =&gt; x1.b, x2 =&gt; new ModelB(x2));

        // Why is this not working??? inferred type for x2 : BaseData
        modelA.Foo2(x1 =&gt; x1.b, x2 =&gt; new ModelB(x2)); // Error
    }
}"><pre class="notranslate"><span class="pl-k">class</span> <span class="pl-smi">ModelA</span><span class="pl-c1">&lt;</span><span class="pl-smi">T</span> <span class="pl-k">extends</span> <span class="pl-smi">BaseData</span><span class="pl-c1">&gt;</span>
<span class="pl-kos">{</span>
    <span class="pl-k">public</span> <span class="pl-c1">prop</span> : <span class="pl-smi">T</span><span class="pl-kos">;</span>

    <span class="pl-k">public</span> <span class="pl-en">constructor</span><span class="pl-kos">(</span><span class="pl-s1">$prop</span> : <span class="pl-smi">T</span><span class="pl-kos">)</span> <span class="pl-kos">{</span> <span class="pl-kos">}</span>

    <span class="pl-k">public</span> <span class="pl-en">Foo</span><span class="pl-c1">&lt;</span><span class="pl-smi">TData</span><span class="pl-kos">,</span> <span class="pl-smi">TModel</span><span class="pl-c1">&gt;</span><span class="pl-kos">(</span>
        <span class="pl-s1">$fn1</span> : <span class="pl-kos">(</span><span class="pl-s1">$x</span> : <span class="pl-smi">T</span><span class="pl-kos">)</span> <span class="pl-c1">=&gt;</span> <span class="pl-smi">TData</span><span class="pl-kos">,</span>
        <span class="pl-s1">$fn2</span> : <span class="pl-kos">(</span><span class="pl-s1">$x</span> : <span class="pl-smi">TData</span><span class="pl-kos">)</span> <span class="pl-c1">=&gt;</span> <span class="pl-smi">TModel</span><span class="pl-kos">)</span> <span class="pl-kos">{</span> <span class="pl-kos">}</span>

    <span class="pl-k">public</span> <span class="pl-en">Foo1</span><span class="pl-c1">&lt;</span><span class="pl-smi">TData</span><span class="pl-kos">,</span> <span class="pl-smi">TModel</span> <span class="pl-k">extends</span> <span class="pl-smi">ModelA</span><span class="pl-kos">&lt;</span><span class="pl-smi">any</span><span class="pl-kos">&gt;</span><span class="pl-c1">&gt;</span><span class="pl-kos">(</span>
        <span class="pl-s1">$fn1</span> : <span class="pl-kos">(</span><span class="pl-s1">$x</span> : <span class="pl-smi">T</span><span class="pl-kos">)</span> <span class="pl-c1">=&gt;</span> <span class="pl-smi">TData</span><span class="pl-kos">,</span>
        <span class="pl-s1">$fn2</span> : <span class="pl-kos">(</span><span class="pl-s1">$x</span> : <span class="pl-smi">TData</span><span class="pl-kos">)</span> <span class="pl-c1">=&gt;</span> <span class="pl-smi">TModel</span><span class="pl-kos">)</span> <span class="pl-kos">{</span> <span class="pl-kos">}</span>

    <span class="pl-k">public</span> <span class="pl-en">Foo2</span><span class="pl-c1">&lt;</span><span class="pl-smi">TData</span> <span class="pl-k">extends</span> <span class="pl-smi">BaseData</span><span class="pl-kos">,</span> <span class="pl-smi">TModel</span> <span class="pl-k">extends</span> <span class="pl-smi">ModelA</span><span class="pl-kos">&lt;</span><span class="pl-smi">TData</span><span class="pl-kos">&gt;</span><span class="pl-c1">&gt;</span><span class="pl-kos">(</span>
        <span class="pl-s1">$fn1</span> : <span class="pl-kos">(</span><span class="pl-s1">$x</span> : <span class="pl-smi">T</span><span class="pl-kos">)</span> <span class="pl-c1">=&gt;</span> <span class="pl-smi">TData</span><span class="pl-kos">,</span>
        <span class="pl-s1">$fn2</span> : <span class="pl-kos">(</span><span class="pl-s1">$x</span> : <span class="pl-smi">TData</span><span class="pl-kos">)</span> <span class="pl-c1">=&gt;</span> <span class="pl-smi">TModel</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">class</span> <span class="pl-smi">ModelB</span> <span class="pl-k">extends</span> <span class="pl-smi">ModelA</span><span class="pl-kos">&lt;</span><span class="pl-smi">Data</span><span class="pl-kos">&gt;</span> <span class="pl-kos">{</span> <span class="pl-kos">}</span>

<span class="pl-k">class</span> <span class="pl-smi">BaseData</span>
<span class="pl-kos">{</span>
    <span class="pl-k">public</span> <span class="pl-c1">a</span> : <span class="pl-smi">string</span><span class="pl-kos">;</span>
<span class="pl-kos">}</span>

<span class="pl-k">class</span> <span class="pl-smi">Data</span> <span class="pl-k">extends</span> <span class="pl-smi">BaseData</span>
<span class="pl-kos">{</span>
    <span class="pl-k">public</span> <span class="pl-c1">b</span> : <span class="pl-smi">Data</span><span class="pl-kos">;</span>
<span class="pl-kos">}</span>

<span class="pl-k">class</span> <span class="pl-smi">P</span>
<span class="pl-kos">{</span>
    <span class="pl-k">public</span> <span class="pl-k">static</span> <span class="pl-en">Run</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">modelA</span> <span class="pl-c1">=</span> <span class="pl-k">new</span> <span class="pl-smi">ModelA</span><span class="pl-kos">&lt;</span><span class="pl-smi">Data</span><span class="pl-kos">&gt;</span><span class="pl-kos">(</span><span class="pl-k">new</span> <span class="pl-smi">Data</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">modelA</span><span class="pl-kos">.</span><span class="pl-en">Foo</span><span class="pl-kos">(</span><span class="pl-s1">x1</span> <span class="pl-c1">=&gt;</span> <span class="pl-s1">x1</span><span class="pl-kos">.</span><span class="pl-c1">b</span><span class="pl-kos">,</span> <span class="pl-s1">x2</span> <span class="pl-c1">=&gt;</span> <span class="pl-k">new</span> <span class="pl-smi">ModelB</span><span class="pl-kos">(</span><span class="pl-s1">x2</span><span class="pl-kos">)</span><span class="pl-kos">)</span><span class="pl-kos">;</span>

        <span class="pl-s1">modelA</span><span class="pl-kos">.</span><span class="pl-en">Foo1</span><span class="pl-kos">(</span><span class="pl-s1">x1</span> <span class="pl-c1">=&gt;</span> <span class="pl-s1">x1</span><span class="pl-kos">.</span><span class="pl-c1">b</span><span class="pl-kos">,</span> <span class="pl-s1">x2</span> <span class="pl-c1">=&gt;</span> <span class="pl-k">new</span> <span class="pl-smi">ModelB</span><span class="pl-kos">(</span><span class="pl-s1">x2</span><span class="pl-kos">)</span><span class="pl-kos">)</span><span class="pl-kos">;</span>

        <span class="pl-c">// Why is this not working??? inferred type for x2 : BaseData</span>
        <span class="pl-s1">modelA</span><span class="pl-kos">.</span><span class="pl-en">Foo2</span><span class="pl-kos">(</span><span class="pl-s1">x1</span> <span class="pl-c1">=&gt;</span> <span class="pl-s1">x1</span><span class="pl-kos">.</span><span class="pl-c1">b</span><span class="pl-kos">,</span> <span class="pl-s1">x2</span> <span class="pl-c1">=&gt;</span> <span class="pl-k">new</span> <span class="pl-smi">ModelB</span><span class="pl-kos">(</span><span class="pl-s1">x2</span><span class="pl-kos">)</span><span class="pl-kos">)</span><span class="pl-kos">;</span> <span class="pl-c">// Error</span>
    <span class="pl-kos">}</span>
<span class="pl-kos">}</span></pre></div>
<p dir="auto"><strong>Expected behavior:</strong><br>
modelA.Foo2 call should infer the type.</p>
<p dir="auto"><strong>Actual behavior:</strong><br>
Is not inferring the actual type.</p>
<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>