<p dir="auto">Since constructor visibility <a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="61017158" data-permission-text="Title is private" data-url="https://github.com/microsoft/TypeScript/issues/2341" data-hovercard-type="issue" data-hovercard-url="/microsoft/TypeScript/issues/2341/hovercard" href="https://github.com/microsoft/TypeScript/issues/2341">#2341</a> got merged. I haven't been able to utilise it fully because the classes I can benefit from requires type parameters and this typings on static methods.</p>
<div class="highlight highlight-source-ts notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="abstract class Model&lt;P&gt; {
    static create(props: P): this {
        let model = window.store[this.name + props.id];
        if (model) {
            return model;
        }
        return window.store[this.name + props.id] = new this(props)
    }

    protected constructor(props: P) {
    }
}"><pre class="notranslate"><span class="pl-k">abstract</span> <span class="pl-k">class</span> <span class="pl-smi">Model</span><span class="pl-c1">&lt;</span><span class="pl-smi">P</span><span class="pl-c1">&gt;</span> <span class="pl-kos">{</span>
    <span class="pl-k">static</span> <span class="pl-en">create</span><span class="pl-kos">(</span><span class="pl-s1">props</span>: <span class="pl-smi">P</span><span class="pl-kos">)</span>: this <span class="pl-kos">{</span>
        <span class="pl-k">let</span> <span class="pl-s1">model</span> <span class="pl-c1">=</span> <span class="pl-smi">window</span><span class="pl-kos">.</span><span class="pl-c1">store</span><span class="pl-kos">[</span><span class="pl-smi">this</span><span class="pl-kos">.</span><span class="pl-c1">name</span> <span class="pl-c1">+</span> <span class="pl-s1">props</span><span class="pl-kos">.</span><span class="pl-c1">id</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-s1">model</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
            <span class="pl-k">return</span> <span class="pl-s1">model</span><span class="pl-kos">;</span>
        <span class="pl-kos">}</span>
        <span class="pl-k">return</span> <span class="pl-smi">window</span><span class="pl-kos">.</span><span class="pl-c1">store</span><span class="pl-kos">[</span><span class="pl-smi">this</span><span class="pl-kos">.</span><span class="pl-c1">name</span> <span class="pl-c1">+</span> <span class="pl-s1">props</span><span class="pl-kos">.</span><span class="pl-c1">id</span><span class="pl-kos">]</span> <span class="pl-c1">=</span> <span class="pl-k">new</span> <span class="pl-smi">this</span><span class="pl-kos">(</span><span class="pl-s1">props</span><span class="pl-kos">)</span>
    <span class="pl-kos">}</span>

    <span class="pl-k">protected</span> <span class="pl-en">constructor</span><span class="pl-kos">(</span><span class="pl-s1">props</span>: <span class="pl-smi">P</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">The <code class="notranslate">Model</code> class is a base class.  A <code class="notranslate">this</code> typing would be very good to refer to the subclass instead of the base class. Since many classes has type arguments in their constructors, it makes sense to allow type arguments in static factory methods as well, otherwise you cannot create type safe factory methods.</p>
<p dir="auto">When trying to implement a fairly basic, but polymorphic, active record style model system we run into issues with the type system not respecting <code class="notranslate">this</code> when used in conjunction with a constructor or template/generic.</p>
<p dir="auto">I've posted before about this here, <a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="114630380" data-permission-text="Title is private" data-url="https://github.com/microsoft/TypeScript/issues/5493" data-hovercard-type="issue" data-hovercard-url="/microsoft/TypeScript/issues/5493/hovercard" href="https://github.com/microsoft/TypeScript/issues/5493">#5493</a>, and <a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="114586216" data-permission-text="Title is private" data-url="https://github.com/microsoft/TypeScript/issues/5492" data-hovercard-type="issue" data-hovercard-url="/microsoft/TypeScript/issues/5492/hovercard" href="https://github.com/microsoft/TypeScript/issues/5492">#5492</a> appears to mention this behavior also.</p>
<p dir="auto">And here is an SO post this that I made:<br>
<a href="http://stackoverflow.com/questions/33443793/create-a-generic-factory-in-typescript-unsolved" rel="nofollow">http://stackoverflow.com/questions/33443793/create-a-generic-factory-in-typescript-unsolved</a></p>
<p dir="auto">I have recycled my example from <a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="114630380" data-permission-text="Title is private" data-url="https://github.com/microsoft/TypeScript/issues/5493" data-hovercard-type="issue" data-hovercard-url="/microsoft/TypeScript/issues/5493/hovercard" href="https://github.com/microsoft/TypeScript/issues/5493">#5493</a> into this ticket for further discussion. I wanted an open ticket representing the desire for such a thing and for discussion but the other two are closed.</p>
<p dir="auto">Here is an example that outlines a model <code class="notranslate">Factory</code> which produces models. If you want to customize the <code class="notranslate">BaseModel</code> that comes back from the <code class="notranslate">Factory</code> you should be able to override it. However this fails because <code class="notranslate">this</code> cannot be used in a static member.</p>
<div class="highlight highlight-source-ts notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="// Typically in a library
export interface InstanceConstructor&lt;T extends BaseModel&gt; {
    new(fac: Factory&lt;T&gt;): T;
}

export class Factory&lt;T extends BaseModel&gt; {
    constructor(private cls: InstanceConstructor&lt;T&gt;) {}

    get() {
        return new this.cls(this);
    }
}

export class BaseModel {
    // NOTE: Does not work....
    constructor(private fac: Factory&lt;this&gt;) {}

    refresh() {
        // get returns a new instance, but it should be of
        // type Model, not BaseModel.
        return this.fac.get();
    }
}

// Application Code
export class Model extends BaseModel {
    do() {
        return true;
    }
}

// Kinda sucks that Factory cannot infer the &quot;Model&quot; type
let f = new Factory&lt;Model&gt;(Model);
let a = f.get();

// b is inferred as any here.
let b = a.refresh();"><pre class="notranslate"><span class="pl-c">// Typically in a library</span>
<span class="pl-k">export</span> <span class="pl-k">interface</span> <span class="pl-smi">InstanceConstructor</span><span class="pl-c1">&lt;</span><span class="pl-smi">T</span> <span class="pl-k">extends</span> <span class="pl-smi">BaseModel</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-s1">fac</span>: <span class="pl-smi">Factory</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-kos">}</span>

<span class="pl-k">export</span> <span class="pl-k">class</span> <span class="pl-smi">Factory</span><span class="pl-c1">&lt;</span><span class="pl-smi">T</span> <span class="pl-k">extends</span> <span class="pl-smi">BaseModel</span><span class="pl-c1">&gt;</span> <span class="pl-kos">{</span>
    <span class="pl-en">constructor</span><span class="pl-kos">(</span><span class="pl-k">private</span> <span class="pl-s1">cls</span>: <span class="pl-smi">InstanceConstructor</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>

    <span class="pl-en">get</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-k">new</span> <span class="pl-smi">this</span><span class="pl-kos">.</span><span class="pl-c1">cls</span><span class="pl-kos">(</span><span class="pl-smi">this</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">export</span> <span class="pl-k">class</span> <span class="pl-smi">BaseModel</span> <span class="pl-kos">{</span>
    <span class="pl-c">// NOTE: Does not work....</span>
    <span class="pl-en">constructor</span><span class="pl-kos">(</span><span class="pl-k">private</span> <span class="pl-s1">fac</span>: <span class="pl-smi">Factory</span><span class="pl-kos">&lt;</span>this<span class="pl-kos">&gt;</span><span class="pl-kos">)</span> <span class="pl-kos">{</span><span class="pl-kos">}</span>

    <span class="pl-en">refresh</span><span class="pl-kos">(</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
        <span class="pl-c">// get returns a new instance, but it should be of</span>
        <span class="pl-c">// type Model, not BaseModel.</span>
        <span class="pl-k">return</span> <span class="pl-smi">this</span><span class="pl-kos">.</span><span class="pl-c1">fac</span><span class="pl-kos">.</span><span class="pl-en">get</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-c">// Application Code</span>
<span class="pl-k">export</span> <span class="pl-k">class</span> <span class="pl-smi">Model</span> <span class="pl-k">extends</span> <span class="pl-smi">BaseModel</span> <span class="pl-kos">{</span>
    <span class="pl-en">do</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-c1">true</span><span class="pl-kos">;</span>
    <span class="pl-kos">}</span>
<span class="pl-kos">}</span>

<span class="pl-c">// Kinda sucks that Factory cannot infer the "Model" type</span>
<span class="pl-k">let</span> <span class="pl-s1">f</span> <span class="pl-c1">=</span> <span class="pl-k">new</span> <span class="pl-smi">Factory</span><span class="pl-kos">&lt;</span><span class="pl-smi">Model</span><span class="pl-kos">&gt;</span><span class="pl-kos">(</span><span class="pl-smi">Model</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
<span class="pl-k">let</span> <span class="pl-s1">a</span> <span class="pl-c1">=</span> <span class="pl-s1">f</span><span class="pl-kos">.</span><span class="pl-en">get</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">;</span>

<span class="pl-c">// b is inferred as any here.</span>
<span class="pl-k">let</span> <span class="pl-s1">b</span> <span class="pl-c1">=</span> <span class="pl-s1">a</span><span class="pl-kos">.</span><span class="pl-en">refresh</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">;</span></pre></div>
<p dir="auto">Maybe this issue is silly and there is an easy workaround. I welcome comments regarding how such a pattern can be achieved.</p>