<p dir="auto">Currently (TS v.1.5.2) the compiler does not do inference correctly for certain cases:</p>
<p dir="auto"><a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="73346636" data-permission-text="Title is private" data-url="https://github.com/microsoft/TypeScript/issues/3038" data-hovercard-type="issue" data-hovercard-url="/microsoft/TypeScript/issues/3038/hovercard" href="https://github.com/microsoft/TypeScript/issues/3038">#3038</a></p>
<p dir="auto">Although it is by design, reflected in the spec and there is no viable way for doing it correctly, I think the compiler has to be honest to the developer and instead of generating faulty code, it has to break with an error message that would say that the inferred types cannot be resolved.</p>
<div class="highlight highlight-source-ts notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="export function keyOf&lt;a&gt;(value: { key: a; }): a {
    return value.key;
}
export interface Data {
    key: number;
    value: Date;
}

var data: Data[] = [];

export function toKeys&lt;a&gt;(values: a[], toKey: (value: a) =&gt; string): string[] {
    return undefined;
}

toKeys(data, keyOf); // &lt;-- actual ok, expected error, since `keyOf` should be inferred as `number` rather than `string`"><pre class="notranslate"><span class="pl-k">export</span> <span class="pl-k">function</span> <span class="pl-en">keyOf</span><span class="pl-c1">&lt;</span><span class="pl-smi">a</span><span class="pl-c1">&gt;</span><span class="pl-kos">(</span><span class="pl-s1">value</span>: <span class="pl-kos">{</span> <span class="pl-c1">key</span>: <span class="pl-smi">a</span><span class="pl-kos">;</span> <span class="pl-kos">}</span><span class="pl-kos">)</span>: <span class="pl-smi">a</span> <span class="pl-kos">{</span>
    <span class="pl-k">return</span> <span class="pl-s1">value</span><span class="pl-kos">.</span><span class="pl-c1">key</span><span class="pl-kos">;</span>
<span class="pl-kos">}</span>
<span class="pl-k">export</span> <span class="pl-k">interface</span> <span class="pl-smi">Data</span> <span class="pl-kos">{</span>
    <span class="pl-c1">key</span>: <span class="pl-smi">number</span><span class="pl-kos">;</span>
    <span class="pl-c1">value</span>: <span class="pl-smi">Date</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-smi">Data</span><span class="pl-kos">[</span><span class="pl-kos">]</span> <span class="pl-c1">=</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">function</span> <span class="pl-en">toKeys</span><span class="pl-c1">&lt;</span><span class="pl-smi">a</span><span class="pl-c1">&gt;</span><span class="pl-kos">(</span><span class="pl-s1">values</span>: <span class="pl-smi">a</span><span class="pl-kos">[</span><span class="pl-kos">]</span><span class="pl-kos">,</span> <span class="pl-s1">toKey</span>: <span class="pl-kos">(</span><span class="pl-s1">value</span>: <span class="pl-smi">a</span><span class="pl-kos">)</span> <span class="pl-c1">=&gt;</span> <span class="pl-smi">string</span><span class="pl-kos">)</span>: <span class="pl-smi">string</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">undefined</span><span class="pl-kos">;</span>
<span class="pl-kos">}</span>

<span class="pl-en">toKeys</span><span class="pl-kos">(</span><span class="pl-s1">data</span><span class="pl-kos">,</span> <span class="pl-s1">keyOf</span><span class="pl-kos">)</span><span class="pl-kos">;</span> <span class="pl-c">// &lt;-- actual ok, expected error, since `keyOf` should be inferred as `number` rather than `string`</span></pre></div>
<p dir="auto"><a target="_blank" rel="noopener noreferrer nofollow" href="https://cloud.githubusercontent.com/assets/937933/7476191/fbf81788-f319-11e4-9a34-82812c01f6e0.png"><img src="https://cloud.githubusercontent.com/assets/937933/7476191/fbf81788-f319-11e4-9a34-82812c01f6e0.png" alt="image" style="max-width: 100%;"></a></p>
<p dir="auto">Reproduced at playground: <a href="http://www.typescriptlang.org/Playground#src=export%20function%20keyOf%3Ca%3E(value%3A%20%7B%20key%3A%20a%3B%20%7D)%3A%20a%20%7B%0A%09return%20value.key%3B%0A%7D%0Aexport%20interface%20Data%20%7B%0A%09key%3A%20number%3B%0A%09value%3A%20Date%3B%0A%7D%0A%0Avar%20data%3A%20Data%5B%5D%20%3D%20%5B%5D%3B%0A%0Aexport%20function%20toKeys%3Ca%3E(values%3A%20a%5B%5D%2C%20toKey%3A%20(value%3A%20a)%20%3D%3E%20string)%3A%20string%5B%5D%20%7B%0A%09return%20undefined%3B%0A%7D%0A%0AtoKeys(data%2C%20keyOf)%3B%20%2F%2F%20%3C--%20expected%20compile%20error%2C%20since%20keyOf%20should%20have%20inferred%20a%20as%20%60number%60%20rather%20than%20%60string%60%0A" rel="nofollow">http://www.typescriptlang.org/Playground#src=export%20function%20keyOf%3Ca%3E(value%3A%20%7B%20key%3A%20a%3B%20%7D)%3A%20a%20%7B%0A%09return%20value.key%3B%0A%7D%0Aexport%20interface%20Data%20%7B%0A%09key%3A%20number%3B%0A%09value%3A%20Date%3B%0A%7D%0A%0Avar%20data%3A%20Data%5B%5D%20%3D%20%5B%5D%3B%0A%0Aexport%20function%20toKeys%3Ca%3E(values%3A%20a%5B%5D%2C%20toKey%3A%20(value%3A%20a)%20%3D%3E%20string)%3A%20string%5B%5D%20%7B%0A%09return%20undefined%3B%0A%7D%0A%0AtoKeys(data%2C%20keyOf)%3B%20%2F%2F%20%3C--%20expected%20compile%20error%2C%20since%20keyOf%20should%20have%20inferred%20a%20as%20%60number%60%20rather%20than%20%60string%60%0A</a></p>