<p dir="auto">One of the common idioms in JavaScript is using a getter function that takes string of a property name of an object and returns the value of the property. For example:</p>
<div class="highlight highlight-source-js notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="var obj = {a: 1, b: '2'};
var model = new Backbone.Model(obj);
var a = mode.get('a'); // a is number"><pre class="notranslate"><span class="pl-k">var</span> <span class="pl-s1">obj</span> <span class="pl-c1">=</span> <span class="pl-kos">{</span><span class="pl-c1">a</span>: <span class="pl-c1">1</span><span class="pl-kos">,</span> <span class="pl-c1">b</span>: <span class="pl-s">'2'</span><span class="pl-kos">}</span><span class="pl-kos">;</span>
<span class="pl-k">var</span> <span class="pl-s1">model</span> <span class="pl-c1">=</span> <span class="pl-k">new</span> <span class="pl-v">Backbone</span><span class="pl-kos">.</span><span class="pl-c1">Model</span><span class="pl-kos">(</span><span class="pl-s1">obj</span><span class="pl-kos">)</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-s1">mode</span><span class="pl-kos">.</span><span class="pl-en">get</span><span class="pl-kos">(</span><span class="pl-s">'a'</span><span class="pl-kos">)</span><span class="pl-kos">;</span> <span class="pl-c">// a is number</span></pre></div>
<p dir="auto">Right now, the <code class="notranslate">get</code> function can only be defined as returning <code class="notranslate">any</code>, because we can't annotate it with anything better. It would be nice to be to define the return type based on the properties of an interface for example:</p>
<div class="highlight highlight-source-ts notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="declare interface Model {
  a: number;
  b: string;
}
declare function get&lt;T as Model[keyArg]&gt;(keyArg: string): T; // syntax is for conveying idea only

get('a'); // number
get('b'); // string
get('c'); // any

declare function get2&lt;T, T2 as T[keyArg]&gt;(keyArg: string): T2; // generic version

get2&lt;Window&gt;('setTimeout'); // function
get2&lt;Window&gt;('nonsense'); // any

declare function get3&lt;T as Model[keyArg]&gt;(keyArg: any): T; // compile error, only support string and maybe number.

declare function set&lt;T as Model[keyArg]&gt;(keyArg: string, value: T): void; // set syntax for the same thing
"><pre class="notranslate"><span class="pl-k">declare</span> <span class="pl-k">interface</span> <span class="pl-smi">Model</span> <span class="pl-kos">{</span>
  <span class="pl-c1">a</span>: <span class="pl-smi">number</span><span class="pl-kos">;</span>
  <span class="pl-c1">b</span>: <span class="pl-smi">string</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">get</span><span class="pl-c1">&lt;</span><span class="pl-smi">T</span> <span class="pl-s1">as</span> <span class="pl-smi">Model</span><span class="pl-kos">[</span><span class="pl-smi">keyArg</span><span class="pl-kos">]</span><span class="pl-c1">&gt;</span><span class="pl-kos">(</span><span class="pl-s1">keyArg</span>: <span class="pl-smi">string</span><span class="pl-kos">)</span>: <span class="pl-smi">T</span><span class="pl-kos">;</span> <span class="pl-c">// syntax is for conveying idea only</span>

<span class="pl-en">get</span><span class="pl-kos">(</span><span class="pl-s">'a'</span><span class="pl-kos">)</span><span class="pl-kos">;</span> <span class="pl-c">// number</span>
<span class="pl-en">get</span><span class="pl-kos">(</span><span class="pl-s">'b'</span><span class="pl-kos">)</span><span class="pl-kos">;</span> <span class="pl-c">// string</span>
<span class="pl-en">get</span><span class="pl-kos">(</span><span class="pl-s">'c'</span><span class="pl-kos">)</span><span class="pl-kos">;</span> <span class="pl-c">// any</span>

<span class="pl-k">declare</span> <span class="pl-k">function</span> <span class="pl-s1">get2</span><span class="pl-c1">&lt;</span><span class="pl-smi">T</span><span class="pl-kos">,</span> <span class="pl-smi">T2</span> <span class="pl-s1">as</span> <span class="pl-smi">T</span><span class="pl-kos">[</span><span class="pl-smi">keyArg</span><span class="pl-kos">]</span><span class="pl-c1">&gt;</span><span class="pl-kos">(</span><span class="pl-s1">keyArg</span>: <span class="pl-smi">string</span><span class="pl-kos">)</span>: <span class="pl-smi">T2</span><span class="pl-kos">;</span> <span class="pl-c">// generic version</span>

<span class="pl-en">get2</span><span class="pl-kos">&lt;</span><span class="pl-smi">Window</span><span class="pl-kos">&gt;</span><span class="pl-kos">(</span><span class="pl-s">'setTimeout'</span><span class="pl-kos">)</span><span class="pl-kos">;</span> <span class="pl-c">// function</span>
<span class="pl-en">get2</span><span class="pl-kos">&lt;</span><span class="pl-smi">Window</span><span class="pl-kos">&gt;</span><span class="pl-kos">(</span><span class="pl-s">'nonsense'</span><span class="pl-kos">)</span><span class="pl-kos">;</span> <span class="pl-c">// any</span>

<span class="pl-k">declare</span> <span class="pl-k">function</span> <span class="pl-s1">get3</span><span class="pl-c1">&lt;</span><span class="pl-smi">T</span> <span class="pl-s1">as</span> <span class="pl-smi">Model</span><span class="pl-kos">[</span><span class="pl-smi">keyArg</span><span class="pl-kos">]</span><span class="pl-c1">&gt;</span><span class="pl-kos">(</span><span class="pl-s1">keyArg</span>: <span class="pl-smi">any</span><span class="pl-kos">)</span>: <span class="pl-smi">T</span><span class="pl-kos">;</span> <span class="pl-c">// compile error, only support string and maybe number.</span>

<span class="pl-k">declare</span> <span class="pl-k">function</span> <span class="pl-s1">set</span><span class="pl-c1">&lt;</span><span class="pl-smi">T</span> <span class="pl-s1">as</span> <span class="pl-smi">Model</span><span class="pl-kos">[</span><span class="pl-smi">keyArg</span><span class="pl-kos">]</span><span class="pl-c1">&gt;</span><span class="pl-kos">(</span><span class="pl-s1">keyArg</span>: <span class="pl-smi">string</span><span class="pl-kos">,</span> <span class="pl-s1">value</span>: <span class="pl-smi">T</span><span class="pl-kos">)</span>: <span class="pl-smi"><span class="pl-k">void</span></span><span class="pl-kos">;</span> <span class="pl-c">// set syntax for the same thing</span></pre></div>
<p dir="auto">This would allow better definitions a lot of functions in common libraries like <code class="notranslate">Lodash</code>/<code class="notranslate">Underscore</code>, <code class="notranslate">Immutable.js</code>, <code class="notranslate">Backbone</code>.</p>
<hr>
<p dir="auto">Currently TypeScript supports specialized overload signature. For example</p>
<div class="highlight highlight-source-ts notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="declare function get(key: string): any;
declare function get(key: 'key'): string;"><pre class="notranslate"><span class="pl-k">declare</span> <span class="pl-k">function</span> <span class="pl-s1">get</span><span class="pl-kos">(</span><span class="pl-s1">key</span>: <span class="pl-smi">string</span><span class="pl-kos">)</span>: <span class="pl-smi">any</span><span class="pl-kos">;</span>
<span class="pl-k">declare</span> <span class="pl-k">function</span> <span class="pl-s1">get</span><span class="pl-kos">(</span><span class="pl-s1">key</span>: <span class="pl-s">'key'</span><span class="pl-kos">)</span>: <span class="pl-smi">string</span><span class="pl-kos">;</span></pre></div>
<p dir="auto">The suggestion above can already be partially implemented at application level by using specialized overload signature with code generator. The suggestion would allow this to be implemented more generally (especially for libraries).</p>
<hr>
<p dir="auto">Potential implementation may also be used to refine <code class="notranslate">{ [key: string]: someType }</code>, but that might be more complex as it requires self referencing.</p>
<p dir="auto">How do I use the compiled typescript files with systemjs? Can typescript compile in the <code class="notranslate">System.register</code> format as traceur can?</p>