<p dir="auto">C# allows adding names of arguments in a function call:</p>
<div class="highlight highlight-source-cs notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="CalculateBMI(weight: 123, height: 64);"><pre class="notranslate">CalculateBMI<span class="pl-kos">(</span>weight<span class="pl-c1">:</span> <span class="pl-c1">123</span><span class="pl-kos">,</span> height<span class="pl-c1">:</span> <span class="pl-c1">64</span><span class="pl-kos">)</span><span class="pl-kos">;</span></pre></div>
<p dir="auto">See <a href="http://msdn.microsoft.com/en-us/library/dd264739.aspx" rel="nofollow">http://msdn.microsoft.com/en-us/library/dd264739.aspx</a></p>
<p dir="auto">In TypeScript's source this is also done, but with comments:</p>
<div class="highlight highlight-source-ts notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="emitLinesStartingAt(nodes, /*startIndex*/ 0);"><pre class="notranslate"><span class="pl-en">emitLinesStartingAt</span><span class="pl-kos">(</span><span class="pl-s1">nodes</span><span class="pl-kos">,</span> <span class="pl-c">/*startIndex*/</span> <span class="pl-c1">0</span><span class="pl-kos">)</span><span class="pl-kos">;</span></pre></div>
<p dir="auto">Can we have named arguments in TypeScript like this:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="emitLinesStartingAt(nodes, startIndex: 0);"><pre class="notranslate"><code class="notranslate">emitLinesStartingAt(nodes, startIndex: 0);
</code></pre></div>
<p dir="auto">This can add some compile time checking, for instance when you type <code class="notranslate">count: 0</code> you will get an error.</p>
<p dir="auto">I think we should add a restriction that the order of the arguments cannot be changed. Example:</p>
<div class="highlight highlight-source-ts notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="function foo(first: number, second: number) {}
var z = 3;
foo(second: z++, first: z);"><pre class="notranslate"><span class="pl-k">function</span> <span class="pl-en">foo</span><span class="pl-kos">(</span><span class="pl-s1">first</span>: <span class="pl-smi">number</span><span class="pl-kos">,</span> <span class="pl-s1">second</span>: <span class="pl-smi">number</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">z</span> <span class="pl-c1">=</span> <span class="pl-c1">3</span><span class="pl-kos">;</span>
<span class="pl-en">foo</span><span class="pl-kos">(</span><span class="pl-s1">second</span>: <span class="pl-s1">z</span><span class="pl-c1">++</span><span class="pl-kos">,</span> <span class="pl-s1">first</span>: <span class="pl-s1">z</span><span class="pl-kos">)</span><span class="pl-kos">;</span></pre></div>
<p dir="auto">An error should be thrown on the last line, because changing the order of the arguments (to <code class="notranslate">foo(z, z++)</code>) in the generated javascript would cause unexpected behavior.</p>
<p dir="auto">Also this can be useful for functions with lots of optional arguments:</p>
<div class="highlight highlight-source-ts notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="function foo(a?, b?, c?, d?, e?) {}
foo(e: 4);
foo(d: 8, 5); // e will be 5"><pre class="notranslate"><span class="pl-k">function</span> <span class="pl-en">foo</span><span class="pl-kos">(</span><span class="pl-s1">a</span>?<span class="pl-kos">,</span> <span class="pl-s1">b</span>?<span class="pl-kos">,</span> <span class="pl-s1">c</span>?<span class="pl-kos">,</span> <span class="pl-s1">d</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-kos">}</span>
<span class="pl-en">foo</span><span class="pl-kos">(</span><span class="pl-s1">e</span>: <span class="pl-c1">4</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
<span class="pl-en">foo</span><span class="pl-kos">(</span><span class="pl-s1">d</span>: <span class="pl-c1">8</span><span class="pl-kos">,</span> <span class="pl-c1">5</span><span class="pl-kos">)</span><span class="pl-kos">;</span> <span class="pl-c">// e will be 5</span></pre></div>
<p dir="auto">Generates</p>
<div class="highlight highlight-source-js notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="function foo(a, b, c, d, e) {}
foo(void 0, void 0, void 0, void 0, 4);
foo(void 0, void 0, void 0, 8, 5);"><pre class="notranslate"><span class="pl-k">function</span> <span class="pl-en">foo</span><span class="pl-kos">(</span><span class="pl-s1">a</span><span class="pl-kos">,</span> <span class="pl-s1">b</span><span class="pl-kos">,</span> <span class="pl-s1">c</span><span class="pl-kos">,</span> <span class="pl-s1">d</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-kos">}</span>
<span class="pl-en">foo</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-k">void</span> <span class="pl-c1">0</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-k">void</span> <span class="pl-c1">0</span><span class="pl-kos">,</span> <span class="pl-c1">4</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
<span class="pl-en">foo</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-k">void</span> <span class="pl-c1">0</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-c1">8</span><span class="pl-kos">,</span> <span class="pl-c1">5</span><span class="pl-kos">)</span><span class="pl-kos">;</span></pre></div>
<h1 dir="auto">Motivation</h1>
<p dir="auto">Verify inputs at application boundary.</p>
<p dir="auto">When a Typescript application interacts with an external system (e.g. receives a Json object from a http request, or receives an object from an external library) a typical approach is to use the cast operator for the input and to assume/hope that the application receives the required type.</p>
<p dir="auto">If/when the external system changes the assumption can be broken resulting in sometimes hard to find bugs and unhelpful runtime errors like "undefined is not a function".</p>
<p dir="auto">These bugs are also quite hard to catch in tests since unit tests isolate the external system, only integration tests would be able to catch these scenarios.</p>
<h1 dir="auto">Proposal</h1>
<p dir="auto">A new cast operator could be introduced that does structural type checking at runtime.<br>
Example:</p>
<div class="highlight highlight-source-js notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="$http.get('https://mySite.com/products', ( result: { data: IProduct[] } ) =&gt;{
    var data:IProduct[] = dynamic_cast&lt;IProduct[]&gt;result.data;
});
"><pre class="notranslate"><span class="pl-s1">$http</span><span class="pl-kos">.</span><span class="pl-en">get</span><span class="pl-kos">(</span><span class="pl-s">'https://mySite.com/products'</span><span class="pl-kos">,</span> <span class="pl-kos">(</span> <span class="pl-s1">result</span>: <span class="pl-kos">{</span> <span class="pl-s1">data</span>: <span class="pl-v">IProduct</span><span class="pl-kos">[</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-kos">{</span>
    <span class="pl-k">var</span> <span class="pl-s1">data</span>:<span class="pl-v">IProduct</span><span class="pl-kos">[</span><span class="pl-s1"></span><span class="pl-kos">]</span> <span class="pl-c1">=</span> <span class="pl-s1">dynamic_cast</span><span class="pl-c1">&lt;</span><span class="pl-v">IProduct</span><span class="pl-kos">[</span><span class="pl-s1"></span><span class="pl-kos">]</span><span class="pl-c1">&gt;</span><span class="pl-s1">result</span><span class="pl-kos">.</span><span class="pl-c1">data</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 Typescript compiler could operate in 2 modes ( debug / release or runtime type checks on/off)</p>
<p dir="auto">In release the compiler would simply remove the dynamic_cast operator.<br>
In debug mode the compiler would wrap the expression in a typeCheck call. It would generate something like this:</p>
<div class="highlight highlight-source-js notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="$http.get('https://mySite.com/products', function( result ) {
    var data:IProduct[] = IProduct.CheckType(result.data);
});"><pre class="notranslate"><span class="pl-s1">$http</span><span class="pl-kos">.</span><span class="pl-en">get</span><span class="pl-kos">(</span><span class="pl-s">'https://mySite.com/products'</span><span class="pl-kos">,</span> <span class="pl-k">function</span><span class="pl-kos">(</span> <span class="pl-s1">result</span> <span class="pl-kos">)</span> <span class="pl-kos">{</span>
    <span class="pl-k">var</span> <span class="pl-s1">data</span>:<span class="pl-v">IProduct</span><span class="pl-kos">[</span><span class="pl-kos">]</span> <span class="pl-c1">=</span> <span class="pl-v">IProduct</span><span class="pl-kos">.</span><span class="pl-en">CheckType</span><span class="pl-kos">(</span><span class="pl-s1">result</span><span class="pl-kos">.</span><span class="pl-c1">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-kos">;</span></pre></div>
<p dir="auto">The tricky bit comes in implementing the CheckType() function.</p>
<p dir="auto">Interfaces that are dynamically checked would suddenly acquire a runtime footprint.</p>
<p dir="auto">Also any interface and Type that appear as the type of members of any interface and type that are type checked would also need to receive a ChekType static member function.</p>
<p dir="auto">It would be still nicer if it would be possible to support a syntax like:</p>
<div class="highlight highlight-source-js notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="$http.get('https://mySite.com/products', ( result: dynamic_cast&lt;{ data: IProduct[] }&gt; ) =&gt;{
    var data:IProduct[] = result.data;
});"><pre class="notranslate"><span class="pl-s1">$http</span><span class="pl-kos">.</span><span class="pl-en">get</span><span class="pl-kos">(</span><span class="pl-s">'https://mySite.com/products'</span><span class="pl-kos">,</span> <span class="pl-kos">(</span> <span class="pl-s1">result</span>: <span class="pl-s1">dynamic_cast</span><span class="pl-c1">&lt;</span><span class="pl-kos">{</span> <span class="pl-c1">data</span>: <span class="pl-v">IProduct</span><span class="pl-kos">[</span><span class="pl-s1"></span><span class="pl-kos">]</span> <span class="pl-kos">}</span><span class="pl-c1">&gt;</span> <span class="pl-kos">)</span> <span class="pl-c1">=&gt;</span><span class="pl-kos">{</span>
    <span class="pl-k">var</span> <span class="pl-s1">data</span>:<span class="pl-v">IProduct</span><span class="pl-kos">[</span><span class="pl-kos">]</span> <span class="pl-c1">=</span> <span class="pl-s1">result</span><span class="pl-kos">.</span><span class="pl-c1">data</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">Although it is not very clear (to me) where would the cast function be scoped and how it would be called, probably the lambda would be wrapped in something ugly like:</p>
<div class="highlight highlight-source-js notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="$http.get('https://mySite.com/products', 
    function (result){
        return (function( result ) {
            var data:IProduct[] = IProduct.CheckType(result.data);
        })( ???.CheckType(result));
});"><pre class="notranslate"><span class="pl-s1">$http</span><span class="pl-kos">.</span><span class="pl-en">get</span><span class="pl-kos">(</span><span class="pl-s">'https://mySite.com/products'</span><span class="pl-kos">,</span> 
    <span class="pl-k">function</span> <span class="pl-kos">(</span><span class="pl-s1">result</span><span class="pl-kos">)</span><span class="pl-kos">{</span>
        <span class="pl-k">return</span> <span class="pl-kos">(</span><span class="pl-k">function</span><span class="pl-kos">(</span> <span class="pl-s1">result</span> <span class="pl-kos">)</span> <span class="pl-kos">{</span>
            <span class="pl-k">var</span> <span class="pl-s1">data</span>:<span class="pl-v">IProduct</span><span class="pl-kos">[</span><span class="pl-kos">]</span> <span class="pl-c1">=</span> <span class="pl-v">IProduct</span><span class="pl-kos">.</span><span class="pl-en">CheckType</span><span class="pl-kos">(</span><span class="pl-s1">result</span><span class="pl-kos">.</span><span class="pl-c1">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-kos">(</span> <span class="pl-c1">??</span><span class="pl-kos">?.</span><span class="pl-v">CheckType</span><span class="pl-kos">(</span><span class="pl-s1">result</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></pre></div>