<p dir="auto"><strong>TypeScript Version:</strong></p>
<p dir="auto">1.8.7</p>
<p dir="auto"><strong>Code</strong></p>
<p dir="auto">file1.ts:</p>
<div class="highlight highlight-source-ts notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="export enum MyEnum {
    FOO
};

export var object1 = {
    foo: MyEnum.FOO
};"><pre class="notranslate"><span class="pl-k">export</span> <span class="pl-k">enum</span> <span class="pl-smi">MyEnum</span> <span class="pl-kos">{</span>
    <span class="pl-c1">FOO</span>
<span class="pl-kos">}</span><span class="pl-kos">;</span>

<span class="pl-k">export</span> <span class="pl-k">var</span> <span class="pl-s1">object1</span> <span class="pl-c1">=</span> <span class="pl-kos">{</span>
    <span class="pl-c1">foo</span>: <span class="pl-smi">MyEnum</span><span class="pl-kos">.</span><span class="pl-c1">FOO</span>
<span class="pl-kos">}</span><span class="pl-kos">;</span></pre></div>
<p dir="auto">file2.ts:</p>
<div class="highlight highlight-source-ts notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="export enum MyEnum {
    BAR
}

export var object2 = {
    foo: MyEnum.BAR
};"><pre class="notranslate"><span class="pl-k">export</span> <span class="pl-k">enum</span> <span class="pl-smi">MyEnum</span> <span class="pl-kos">{</span>
    <span class="pl-c1">BAR</span>
<span class="pl-kos">}</span>

<span class="pl-k">export</span> <span class="pl-k">var</span> <span class="pl-s1">object2</span> <span class="pl-c1">=</span> <span class="pl-kos">{</span>
    <span class="pl-c1">foo</span>: <span class="pl-smi">MyEnum</span><span class="pl-kos">.</span><span class="pl-c1">BAR</span>
<span class="pl-kos">}</span><span class="pl-kos">;</span></pre></div>
<p dir="auto">file3.ts</p>
<div class="highlight highlight-source-ts notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="import * as file1 from &quot;./file1&quot;;
import * as file2 from &quot;./file2&quot;;

let broken = [
    file1.object1,
    file2.object2
];"><pre class="notranslate"><span class="pl-k">import</span> <span class="pl-c1">*</span> <span class="pl-k">as</span> <span class="pl-s1">file1</span> <span class="pl-k">from</span> <span class="pl-s">"./file1"</span><span class="pl-kos">;</span>
<span class="pl-k">import</span> <span class="pl-c1">*</span> <span class="pl-k">as</span> <span class="pl-s1">file2</span> <span class="pl-k">from</span> <span class="pl-s">"./file2"</span><span class="pl-kos">;</span>

<span class="pl-k">let</span> <span class="pl-s1">broken</span> <span class="pl-c1">=</span> <span class="pl-kos">[</span>
    <span class="pl-s1">file1</span><span class="pl-kos">.</span><span class="pl-c1">object1</span><span class="pl-kos">,</span>
    <span class="pl-s1">file2</span><span class="pl-kos">.</span><span class="pl-c1">object2</span>
<span class="pl-kos">]</span><span class="pl-kos">;</span></pre></div>
<p dir="auto">Run tsc file1.ts file2.ts file3.ts<br>
<strong>Expected behavior:</strong><br>
Either compiler emits an error saying that it cannot find a common type for <code class="notranslate">broken</code>, or compilation succeeds.</p>
<p dir="auto"><strong>Actual behavior:</strong></p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="/usr/local/lib/node_modules/typescript/lib/tsc.js:32996
                throw e;
                ^

Error: Debug Failure. False expression: 
    at Object.assert (/usr/local/lib/node_modules/typescript/lib/tsc.js:757:23)
    at reportError (/usr/local/lib/node_modules/typescript/lib/tsc.js:15894:26)
    at enumRelatedTo (/usr/local/lib/node_modules/typescript/lib/tsc.js:16444:29)
    at isRelatedTo (/usr/local/lib/node_modules/typescript/lib/tsc.js:15922:34)
    at propertiesRelatedTo (/usr/local/lib/node_modules/typescript/lib/tsc.js:16256:43)
    at objectTypeRelatedTo (/usr/local/lib/node_modules/typescript/lib/tsc.js:16178:30)
    at isRelatedTo (/usr/local/lib/node_modules/typescript/lib/tsc.js:15991:38)
    at checkTypeRelatedTo (/usr/local/lib/node_modules/typescript/lib/tsc.js:15882:26)
    at checkTypeSubtypeOf (/usr/local/lib/node_modules/typescript/lib/tsc.js:15757:20)
    at isTypeSubtypeOf (/usr/local/lib/node_modules/typescript/lib/tsc.js:15751:20)"><pre class="notranslate"><code class="notranslate">/usr/local/lib/node_modules/typescript/lib/tsc.js:32996
                throw e;
                ^

Error: Debug Failure. False expression: 
    at Object.assert (/usr/local/lib/node_modules/typescript/lib/tsc.js:757:23)
    at reportError (/usr/local/lib/node_modules/typescript/lib/tsc.js:15894:26)
    at enumRelatedTo (/usr/local/lib/node_modules/typescript/lib/tsc.js:16444:29)
    at isRelatedTo (/usr/local/lib/node_modules/typescript/lib/tsc.js:15922:34)
    at propertiesRelatedTo (/usr/local/lib/node_modules/typescript/lib/tsc.js:16256:43)
    at objectTypeRelatedTo (/usr/local/lib/node_modules/typescript/lib/tsc.js:16178:30)
    at isRelatedTo (/usr/local/lib/node_modules/typescript/lib/tsc.js:15991:38)
    at checkTypeRelatedTo (/usr/local/lib/node_modules/typescript/lib/tsc.js:15882:26)
    at checkTypeSubtypeOf (/usr/local/lib/node_modules/typescript/lib/tsc.js:15757:20)
    at isTypeSubtypeOf (/usr/local/lib/node_modules/typescript/lib/tsc.js:15751:20)
</code></pre></div>
<p dir="auto">Note that casting the array explicitly, eg:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="let broken: any[] = [
    file1.object1,
    file2.object2
];

let broken: any = [
    file1.object1,
    file2.object2
];

let broken = [
    file1.object1,
    file2.object2
] as any;

let broken = &lt;any[]&gt;[
    file1.object1,
    file2.object2
];"><pre class="notranslate"><code class="notranslate">let broken: any[] = [
    file1.object1,
    file2.object2
];

let broken: any = [
    file1.object1,
    file2.object2
];

let broken = [
    file1.object1,
    file2.object2
] as any;

let broken = &lt;any[]&gt;[
    file1.object1,
    file2.object2
];
</code></pre></div>
<p dir="auto">all fail, but casting either object1 or object2 to any would make compilation succeed. For example,</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="let broken = [
    file1.object1 as any,
    file2.object2
];"><pre class="notranslate"><code class="notranslate">let broken = [
    file1.object1 as any,
    file2.object2
];
</code></pre></div>
<p dir="auto">I'm guessing this is because the compiler does a subtype checking <em>after</em> it figures out the array type (which it fails to).</p>
<p dir="auto"><strong>TypeScript Version:</strong></p>
<p dir="auto">1.7.5 / 1.8.0-beta / nightly (1.9.0-dev.20160217)</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="// try augmenting the SymbolContructor to have some expected symbol on it.
// in RxJS5's case, it'll be the Symbol.observable symbol from the es-observable spec.
interface SymbolConstructor {
  observable: symbol;
}

interface Observablesque&lt;T&gt; {
  [Symbol.observable]: () =&gt; Subscribable&lt;T&gt;
}"><pre class="notranslate"><span class="pl-c">// try augmenting the SymbolContructor to have some expected symbol on it.</span>
<span class="pl-c">// in RxJS5's case, it'll be the Symbol.observable symbol from the es-observable spec.</span>
<span class="pl-k">interface</span> <span class="pl-smi">SymbolConstructor</span> <span class="pl-kos">{</span>
  <span class="pl-c1">observable</span>: <span class="pl-smi">symbol</span><span class="pl-kos">;</span>
<span class="pl-kos">}</span>

<span class="pl-k">interface</span> <span class="pl-smi">Observablesque</span><span class="pl-c1">&lt;</span><span class="pl-smi">T</span><span class="pl-c1">&gt;</span> <span class="pl-kos">{</span>
  <span class="pl-kos">[</span><span class="pl-smi">Symbol</span><span class="pl-kos">.</span><span class="pl-c1">observable</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-smi">Subscribable</span><span class="pl-kos">&lt;</span><span class="pl-smi">T</span><span class="pl-kos">&gt;</span>
<span class="pl-kos">}</span></pre></div>
<p dir="auto">or</p>
<div class="highlight highlight-source-ts notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="// try importing some symbol reference (I get why this might not work)
import {$$observable} from './symbol/observable';

interface Observablesque&lt;T&gt; {
  [$$observable]: () =&gt; Subscribable&lt;T&gt;
}"><pre class="notranslate"><span class="pl-c">// try importing some symbol reference (I get why this might not work)</span>
<span class="pl-k">import</span> <span class="pl-kos">{</span><span class="pl-s1">$$observable</span><span class="pl-kos">}</span> <span class="pl-k">from</span> <span class="pl-s">'./symbol/observable'</span><span class="pl-kos">;</span>

<span class="pl-k">interface</span> <span class="pl-smi">Observablesque</span><span class="pl-c1">&lt;</span><span class="pl-smi">T</span><span class="pl-c1">&gt;</span> <span class="pl-kos">{</span>
  <span class="pl-kos">[</span><span class="pl-s1">$$observable</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-smi">Subscribable</span><span class="pl-kos">&lt;</span><span class="pl-smi">T</span><span class="pl-kos">&gt;</span>
<span class="pl-kos">}</span></pre></div>
<p dir="auto"><strong>Expected behavior:</strong></p>
<p dir="auto">I should be able to enforce types that have symbols on them, custom or otherwise.</p>
<p dir="auto"><strong>Actual behavior:</strong></p>
<p dir="auto">I get really confused and go get myself a coffee.</p>