<p dir="auto"><strong>TypeScript Version:</strong></p>
<p dir="auto">1.8.9</p>
<p dir="auto">This is from <a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="150591109" data-permission-text="Title is private" data-url="https://github.com/microsoft/vscode/issues/5699" data-hovercard-type="issue" data-hovercard-url="/microsoft/vscode/issues/5699/hovercard" href="https://github.com/microsoft/vscode/issues/5699">microsoft/vscode#5699</a> but the essence is that setting <code class="notranslate">allowJS: true</code> in jsconfig.json breaks the <code class="notranslate">projectInfo</code> call in tsserver.</p>
<p dir="auto">Steps and sources to repo can be found in <a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="150591109" data-permission-text="Title is private" data-url="https://github.com/microsoft/vscode/issues/5699" data-hovercard-type="issue" data-hovercard-url="/microsoft/vscode/issues/5699/hovercard" href="https://github.com/microsoft/vscode/issues/5699">microsoft/vscode#5699</a>.</p>
<p dir="auto">Knockout models, which are very concise in javascript, are obnoxious to define in typescript (one of the few things that gets <em>longer</em> in typescript).  I'm suggesting the following syntax to make it much cleaner.  (Perhaps this is a duplicate?)</p>
<p dir="auto">This syntax adds a constructor signature with parameters which can be referenced in the field initializers.  This is to replace javascript's easy <code class="notranslate">this.someNewProperty = '...'</code> legitimacy while retaining the strong typing information of typescript (that is, not resorting to a cast as <code class="notranslate">any</code>, etc)</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="class koSubModel(node: any = {}) {
    public a = ko.observable&lt;number&gt;(node.a || 0);
    public b = ko.observable&lt;string&gt;(node.b);
}

class koModel(node: any = {}) {
    public one = ko.observable&lt;number&gt;(node.one || 0);
    public two = ko.observable&lt;string&gt;(node.two || '[missing data]');
    public three = ko.observableArray&lt;number&gt;(node.three || []);
    public four = ko.observableArray&lt;koSubModel&gt;((node.four || []).map(e =&gt; new koSubModel(e)));
}

// example usage
$.getJSON('...', data =&gt; ko.applyBindings(new koModel(data)));"><pre class="notranslate"><code class="notranslate">class koSubModel(node: any = {}) {
    public a = ko.observable&lt;number&gt;(node.a || 0);
    public b = ko.observable&lt;string&gt;(node.b);
}

class koModel(node: any = {}) {
    public one = ko.observable&lt;number&gt;(node.one || 0);
    public two = ko.observable&lt;string&gt;(node.two || '[missing data]');
    public three = ko.observableArray&lt;number&gt;(node.three || []);
    public four = ko.observableArray&lt;koSubModel&gt;((node.four || []).map(e =&gt; new koSubModel(e)));
}

// example usage
$.getJSON('...', data =&gt; ko.applyBindings(new koModel(data)));
</code></pre></div>
<p dir="auto">The generated model seems pretty much what you'd write by hand:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="var koSubModel = (function () {
    function koSubModel(node) {
        if (typeof node === &quot;undefined&quot;) { node = {}; }
        this.a = ko.observable(node.a || 0);
        this.b = ko.observable(node.b);
    };
    return koSubModel;
})();

var koModel = (function () {
    function koModel(node) {
        if (typeof node === &quot;undefined&quot;) { node = {}; }
        this.one = ko.observable(node.one || 0);
        this.two = ko.observable(node.two || '[missing data]');
        this.three = ko.observableArray((node.three || []));
        this.four = ko.observableArray((node.four || []).map(function (e) { return new koSubModel(e); }));
    };
    return koModel;
})();"><pre class="notranslate"><code class="notranslate">var koSubModel = (function () {
    function koSubModel(node) {
        if (typeof node === "undefined") { node = {}; }
        this.a = ko.observable(node.a || 0);
        this.b = ko.observable(node.b);
    };
    return koSubModel;
})();

var koModel = (function () {
    function koModel(node) {
        if (typeof node === "undefined") { node = {}; }
        this.one = ko.observable(node.one || 0);
        this.two = ko.observable(node.two || '[missing data]');
        this.three = ko.observableArray((node.three || []));
        this.four = ko.observableArray((node.four || []).map(function (e) { return new koSubModel(e); }));
    };
    return koModel;
})();
</code></pre></div>
<p dir="auto">The alternative (current way) is that all the fields have to be declared and separately assigned in a constructor:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="class koSubModel_ {
    public a : KnockoutObservable&lt;number&gt;;
    public b : KnockoutObservable&lt;string&gt;;

    constructor(node : any = {}) {
        this.a = ko.observable&lt;number&gt;(node.a || 0);
        this.b = ko.observable&lt;string&gt;(node.b);
    }
}

class koModel_ {
    public one : KnockoutObservable&lt;number&gt;;
    public two : KnockoutObservable&lt;string&gt;;
    public three : KnockoutObservableArray&lt;number&gt;;
    public four : KnockoutObservableArray&lt;koSubModel_&gt;;

    constructor(node: any = {}) {
        this.one = ko.observable&lt;number&gt;(node.one || 0);
        this.two = ko.observable&lt;string&gt;(node.two || '[missing data]');
        this.three = ko.observableArray&lt;number&gt;(node.three || []);
        this.four = ko.observableArray&lt;koSubModel_&gt;((node.four || []).map(e =&gt; new koSubModel_(e)));
    }
}"><pre class="notranslate"><code class="notranslate">class koSubModel_ {
    public a : KnockoutObservable&lt;number&gt;;
    public b : KnockoutObservable&lt;string&gt;;

    constructor(node : any = {}) {
        this.a = ko.observable&lt;number&gt;(node.a || 0);
        this.b = ko.observable&lt;string&gt;(node.b);
    }
}

class koModel_ {
    public one : KnockoutObservable&lt;number&gt;;
    public two : KnockoutObservable&lt;string&gt;;
    public three : KnockoutObservableArray&lt;number&gt;;
    public four : KnockoutObservableArray&lt;koSubModel_&gt;;

    constructor(node: any = {}) {
        this.one = ko.observable&lt;number&gt;(node.one || 0);
        this.two = ko.observable&lt;string&gt;(node.two || '[missing data]');
        this.three = ko.observableArray&lt;number&gt;(node.three || []);
        this.four = ko.observableArray&lt;koSubModel_&gt;((node.four || []).map(e =&gt; new koSubModel_(e)));
    }
}
</code></pre></div>