<p dir="auto">Hi,</p>
<p dir="auto">I'm having trouble calling a function of another module that receives an argument with a type from a third distinct module. I hope the explanation bellow helps you get a sense of the problem.</p>
<p dir="auto"><strong>TypeScript Version:</strong></p>
<p dir="auto">1.8.9</p>
<p dir="auto">We have the following folder structure. ProjectB depends on ProjectA. Both depend on Angular2.</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="| -- Solution
      | -- projectA
            | -- node_modules
                  | -- angular2
      | -- projectB
            | -- node_modules
                  | -- angular2
                  | -- projectA"><pre class="notranslate"><code class="notranslate">| -- Solution
      | -- projectA
            | -- node_modules
                  | -- angular2
      | -- projectB
            | -- node_modules
                  | -- angular2
                  | -- projectA
</code></pre></div>
<p dir="auto">Note: We use node as resolution strategy. angular2 folder is, in both cases, a symlink and both point to the same concrete folder, so the files inside them are exactly the same.</p>
<p dir="auto"><strong>Code</strong></p>
<p dir="auto">On Project A, we have a class that has something like this:</p>
<div class="highlight highlight-source-ts notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="
public navigateByAction(router: ngRouter.Router): Promise&lt;void&gt;"><pre class="notranslate"><span class="pl-k">public</span> <span class="pl-en">navigateByAction</span><span class="pl-kos">(</span><span class="pl-s1">router</span>: <span class="pl-s1">ngRouter</span><span class="pl-kos">.</span><span class="pl-c1">Router</span><span class="pl-kos">)</span>: <span class="pl-smi">Promise</span><span class="pl-kos">&lt;</span><span class="pl-smi"><span class="pl-k">void</span></span><span class="pl-kos">&gt;</span></pre></div>
<p dir="auto">On Project B, we have:</p>
<div class="highlight highlight-source-ts notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="import * as ngRouter from &quot;angular2/router&quot;;
import * as projectA from &quot;projectA/main&quot;;

...
public router: ngRouter.Router;
....

// Eventually we call a method from projectA.
projectA.navigateByAction(this.router);"><pre class="notranslate"><span class="pl-k">import</span> <span class="pl-c1">*</span> <span class="pl-k">as</span> <span class="pl-s1">ngRouter</span> <span class="pl-k">from</span> <span class="pl-s">"angular2/router"</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">projectA</span> <span class="pl-k">from</span> <span class="pl-s">"projectA/main"</span><span class="pl-kos">;</span>

...
public <span class="pl-s1">router</span>: <span class="pl-s1">ngRouter</span><span class="pl-kos">.</span><span class="pl-c1">Router</span><span class="pl-kos">;</span>
...<span class="pl-kos">.</span>

<span class="pl-c">// Eventually we call a method from projectA.</span>
<span class="pl-s1">projectA</span><span class="pl-kos">.</span><span class="pl-en">navigateByAction</span><span class="pl-kos">(</span><span class="pl-smi">this</span><span class="pl-kos">.</span><span class="pl-c1">router</span><span class="pl-kos">)</span><span class="pl-kos">;</span></pre></div>
<p dir="auto"><strong>Expected behavior:</strong><br>
No TS Compiler error.</p>
<p dir="auto"><strong>Actual behavior:</strong><br>
Argument of type 'Router' is not assignable to parameter of type 'Router'.<br>
Types have separate declarations of a private property '_rootComponent'.</p>
<h2 dir="auto">Workarounds</h2>
<h3 dir="auto">Workaround 1</h3>
<p dir="auto">If I change the structure of the project to something like the following it works fine.<br>
This is not the way we want to move forward because each module should have it's own dependencies and not rely on a parent for dependency resolution.</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="| -- Solution
      | -- node_modules
            | -- angular2
      | -- projectA
      | -- projectB
            | -- node_modules
                  | -- projectA"><pre class="notranslate"><code class="notranslate">| -- Solution
      | -- node_modules
            | -- angular2
      | -- projectA
      | -- projectB
            | -- node_modules
                  | -- projectA
</code></pre></div>
<h3 dir="auto">Workaround 2</h3>
<p dir="auto">Casting to any before calling the function will of course stop the error on the compiler. Definitely not the solution we are looking for in the long term.</p>
<p dir="auto">The error relates to enums, and exports using the new typescript node resolution (with the typings property in the package.json). I have tested this on typescript@next.</p>
<p dir="auto">The bug can be reproduced through the following scenario: (please go to <a href="https://github.com/christyharagan/typeScript-enum-export-bug">https://github.com/christyharagan/typeScript-enum-export-bug</a> to find this code):</p>
<p dir="auto">Three projects: <code class="notranslate">a</code>, <code class="notranslate">b</code>, <code class="notranslate">c</code>.</p>
<p dir="auto"><code class="notranslate">b</code> depends on <code class="notranslate">a</code><br>
<code class="notranslate">c</code> depends on <code class="notranslate">b</code></p>
<p dir="auto"><code class="notranslate">a</code> exports an enum through its index.ts:</p>
<div class="highlight highlight-source-ts notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="export enum E{}"><pre class="notranslate"><span class="pl-k">export</span> <span class="pl-k">enum</span> <span class="pl-smi">E</span><span class="pl-kos">{</span><span class="pl-kos">}</span></pre></div>
<p dir="auto"><code class="notranslate">b</code> then exports a function that returns <code class="notranslate">E</code> through its index.ts:</p>
<div class="highlight highlight-source-ts notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="import {E} from 'a'
export function f():E {
  return null
}"><pre class="notranslate"><span class="pl-k">import</span> <span class="pl-kos">{</span><span class="pl-smi">E</span><span class="pl-kos">}</span> <span class="pl-k">from</span> <span class="pl-s">'a'</span>
<span class="pl-k">export</span> <span class="pl-k">function</span> <span class="pl-en">f</span><span class="pl-kos">(</span><span class="pl-kos">)</span>:<span class="pl-smi">E</span> <span class="pl-kos">{</span>
  <span class="pl-k">return</span> <span class="pl-c1">null</span>
<span class="pl-kos">}</span></pre></div>
<p dir="auto"><code class="notranslate">c</code> then consumes <code class="notranslate">f</code> through its index.ts:</p>
<div class="highlight highlight-source-ts notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="import {E} from 'a'
import {f} from 'b'

let e:E = f()"><pre class="notranslate"><span class="pl-k">import</span> <span class="pl-kos">{</span><span class="pl-smi">E</span><span class="pl-kos">}</span> <span class="pl-k">from</span> <span class="pl-s">'a'</span>
<span class="pl-k">import</span> <span class="pl-kos">{</span><span class="pl-s1">f</span><span class="pl-kos">}</span> <span class="pl-k">from</span> <span class="pl-s">'b'</span>

<span class="pl-k">let</span> <span class="pl-s1">e</span>:<span class="pl-smi">E</span> <span class="pl-c1">=</span> <span class="pl-en">f</span><span class="pl-kos">(</span><span class="pl-kos">)</span></pre></div>
<p dir="auto">There is now an error for <code class="notranslate">e</code>:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="Type 'E' is not assignable to type 'E'."><pre class="notranslate"><code class="notranslate">Type 'E' is not assignable to type 'E'.
</code></pre></div>
<p dir="auto">All three packages have a package.json that looks like this:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="{
  &quot;name&quot;: &quot;b&quot;,
  &quot;version&quot;: &quot;1&quot;,
  &quot;main&quot;: &quot;lib/index.js&quot;,
  &quot;typings&quot;: &quot;lib/index.d.ts&quot;,
  &quot;dependencies&quot;: {
    &quot;a&quot;: &quot;1&quot;
  }
}"><pre class="notranslate"><code class="notranslate">{
  "name": "b",
  "version": "1",
  "main": "lib/index.js",
  "typings": "lib/index.d.ts",
  "dependencies": {
    "a": "1"
  }
}
</code></pre></div>
<p dir="auto">And a tsconfig.json that looks like:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="{
    &quot;compilerOptions&quot;: {
        &quot;declaration&quot;: true,
        &quot;module&quot;: &quot;commonjs&quot;,
        &quot;rootDir&quot;: &quot;./src&quot;,
        &quot;target&quot;: &quot;es5&quot;,
        &quot;outDir&quot;: &quot;./lib&quot;
    },
    &quot;files&quot;: [
        &quot;src/index.ts&quot;
    ]
}"><pre class="notranslate"><code class="notranslate">{
    "compilerOptions": {
        "declaration": true,
        "module": "commonjs",
        "rootDir": "./src",
        "target": "es5",
        "outDir": "./lib"
    },
    "files": [
        "src/index.ts"
    ]
}
</code></pre></div>
<p dir="auto">Furthermore, this defect occurs if <code class="notranslate">f</code> were to export another symbol (e.g. an interface) which references an exported enum somewhere within it's structure or hierarchy.</p>
<p dir="auto">This only seems to affect enums, not other types.</p>