<p dir="auto">Sorry about the bug title, I don’t know exactly the best way to phrase it.</p>
<p dir="auto">Given the following code:</p>
<div class="highlight highlight-source-ts notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="interface A {
  (key:'foo'):string;
  (key:string):void;
}

interface A1 extends A {
  (key:'bar'):string;
}

interface A2 extends A {
  (key:'baz'):string;
}

interface B extends A1, A2 {
  (key:'blah'):string;
}

var b:B;

b('foo').length; // OK
b('bar').length; // OK
b('baz').length; // Error
b('blah').length; // OK"><pre class="notranslate"><span class="pl-k">interface</span> <span class="pl-smi">A</span> <span class="pl-kos">{</span>
  <span class="pl-kos">(</span><span class="pl-s1">key</span>:<span class="pl-s">'foo'</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-s1">key</span>:<span class="pl-smi">string</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-kos">}</span>

<span class="pl-k">interface</span> <span class="pl-smi">A1</span> <span class="pl-k">extends</span> <span class="pl-smi">A</span> <span class="pl-kos">{</span>
  <span class="pl-kos">(</span><span class="pl-s1">key</span>:<span class="pl-s">'bar'</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-k">interface</span> <span class="pl-smi">A2</span> <span class="pl-k">extends</span> <span class="pl-smi">A</span> <span class="pl-kos">{</span>
  <span class="pl-kos">(</span><span class="pl-s1">key</span>:<span class="pl-s">'baz'</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-k">interface</span> <span class="pl-smi">B</span> <span class="pl-k">extends</span> <span class="pl-smi">A1</span><span class="pl-kos">,</span> <span class="pl-smi">A2</span> <span class="pl-kos">{</span>
  <span class="pl-kos">(</span><span class="pl-s1">key</span>:<span class="pl-s">'blah'</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-k">var</span> <span class="pl-s1">b</span>:<span class="pl-smi">B</span><span class="pl-kos">;</span>

<span class="pl-en">b</span><span class="pl-kos">(</span><span class="pl-s">'foo'</span><span class="pl-kos">)</span><span class="pl-kos">.</span><span class="pl-c1">length</span><span class="pl-kos">;</span> <span class="pl-c">// OK</span>
<span class="pl-en">b</span><span class="pl-kos">(</span><span class="pl-s">'bar'</span><span class="pl-kos">)</span><span class="pl-kos">.</span><span class="pl-c1">length</span><span class="pl-kos">;</span> <span class="pl-c">// OK</span>
<span class="pl-en">b</span><span class="pl-kos">(</span><span class="pl-s">'baz'</span><span class="pl-kos">)</span><span class="pl-kos">.</span><span class="pl-c1">length</span><span class="pl-kos">;</span> <span class="pl-c">// Error</span>
<span class="pl-en">b</span><span class="pl-kos">(</span><span class="pl-s">'blah'</span><span class="pl-kos">)</span><span class="pl-kos">.</span><span class="pl-c1">length</span><span class="pl-kos">;</span> <span class="pl-c">// OK</span></pre></div>
<p dir="auto">The resulting list of overloads is:</p>
<div class="highlight highlight-source-ts notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="(key:'blah'):string;
(key:'bar'):string;
(key:'foo'):string;
(key:string):void;
(key:'baz'):string;
(key:'foo'):string;
(key:string):void;"><pre class="notranslate"><span class="pl-kos">(</span><span class="pl-s1">key</span>:<span class="pl-s">'blah'</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-s1">key</span>:<span class="pl-s">'bar'</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-s1">key</span>:<span class="pl-s">'foo'</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-s1">key</span>:<span class="pl-smi">string</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-kos">(</span><span class="pl-s1">key</span>:<span class="pl-s">'baz'</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-s1">key</span>:<span class="pl-s">'foo'</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-s1">key</span>:<span class="pl-smi">string</span><span class="pl-kos">)</span>:<span class="pl-smi"><span class="pl-k">void</span></span><span class="pl-kos">;</span></pre></div>
<p dir="auto">As a result, calling <code class="notranslate">b('baz')</code> resolves to <code class="notranslate">void</code> type since the 4th item in the list is the first one that matches, but this does not match the author’s expectation. Section 7.2 of the spec doesn’t really address the case where multiple inheritance creates an inheritance graph that splits and joins.</p>
<p dir="auto">The author’s expectation is that the duplicate <code class="notranslate">A</code> superclass overload options would be eliminated so the total overload list would look more like this:</p>
<div class="highlight highlight-source-ts notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="(key:'blah'):string;
(key:'baz'):string;
(key:'bar'):string;
(key:'foo'):string;
(key:string):string;"><pre class="notranslate"><span class="pl-kos">(</span><span class="pl-s1">key</span>:<span class="pl-s">'blah'</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-s1">key</span>:<span class="pl-s">'baz'</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-s1">key</span>:<span class="pl-s">'bar'</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-s1">key</span>:<span class="pl-s">'foo'</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-s1">key</span>:<span class="pl-smi">string</span><span class="pl-kos">)</span>:<span class="pl-smi">string</span><span class="pl-kos">;</span></pre></div>
<p dir="auto">The expected list above starts with A2, not A1 as the current compiler seems to do, but that part is somewhat less important than the fact that signatures from <code class="notranslate">A</code> are being duplicated in the calculated overload list. At minimum I’d hope that the compiler could reorder the list so that the non-specialized signature in a list of specialized signatures always goes to the bottom.</p>
<p dir="auto">Thoughts?</p>
<p dir="auto"><strong>TypeScript Version:</strong></p>
<p dir="auto">nightly (1.9.0-dev.20160515)</p>
<p dir="auto"><strong>Code</strong></p>
<div class="highlight highlight-source-ts notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="var a: '_RESULT' = '_RESULT';
var b: '__RESULT' = '__RESULT';"><pre class="notranslate"><span class="pl-k">var</span> <span class="pl-s1">a</span>: <span class="pl-s">'_RESULT'</span> <span class="pl-c1">=</span> <span class="pl-s">'_RESULT'</span><span class="pl-kos">;</span>
<span class="pl-k">var</span> <span class="pl-s1">b</span>: <span class="pl-s">'__RESULT'</span> <span class="pl-c1">=</span> <span class="pl-s">'__RESULT'</span><span class="pl-kos">;</span></pre></div>
<p dir="auto"><strong>Expected behavior:</strong><br>
Both variables are assigned with no errors.</p>
<p dir="auto"><strong>Actual behavior:</strong><br>
<code class="notranslate">a</code> is assigned with no errors, but <code class="notranslate">b</code> reports type mismatch. This happens whenever I use strings tagged with <code class="notranslate">__</code> (double-underscore) as a prefix.</p>