Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dependency module resolution -- type mismatch #7828

Closed
jpsfs opened this issue Apr 5, 2016 · 1 comment
Closed

Dependency module resolution -- type mismatch #7828

jpsfs opened this issue Apr 5, 2016 · 1 comment
Labels
Duplicate An existing issue was already created

Comments

@jpsfs
Copy link

jpsfs commented Apr 5, 2016

Hi,

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.

TypeScript Version:

1.8.9

We have the following folder structure. ProjectB depends on ProjectA. Both depend on Angular2.

| -- Solution
      | -- projectA
            | -- node_modules
                  | -- angular2
      | -- projectB
            | -- node_modules
                  | -- angular2
                  | -- projectA

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.

Code

On Project A, we have a class that has something like this:

public navigateByAction(router: ngRouter.Router): Promise<void>

On Project B, we have:

import * as ngRouter from "angular2/router";
import * as projectA from "projectA/main";

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

// Eventually we call a method from projectA.
projectA.navigateByAction(this.router);

Expected behavior:
No TS Compiler error.

Actual behavior:
Argument of type 'Router' is not assignable to parameter of type 'Router'.
Types have separate declarations of a private property '_rootComponent'.

Workarounds

Workaround 1

If I change the structure of the project to something like the following it works fine.
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.

| -- Solution
      | -- node_modules
            | -- angular2
      | -- projectA
      | -- projectB
            | -- node_modules
                  | -- projectA

Workaround 2

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.

@mhegazy
Copy link
Contributor

mhegazy commented Apr 5, 2016

This is duplicate of #4800.

Given this folder hierarchy, it is possible at runtime that you have two different versions of the angular2. I am guessing you have some post build step that combines the output in one directory, and reference angular2 through a CDN perhaps, but that is not obvious to the compiler.

The only thing it sees is two classes that you are trying to pass one for the other, and they have the same shape, but at least one of them have a private/protected member, and that is deemed un-safe.

options, 1. your first workaround would be one option, 2. use "paths", assuming that my statements earlier about a post-build step is accurate. you can define something like:

"compilerOptions":{
  "paths": {
     // always resolve angular2 imports to `projectA/node_modules/angular2`
     "angular2/*": [ "projectA/node_modules/angular2/*" ]
  }
}

See more information about path mapping at https://github.com/Microsoft/TypeScript-Handbook/blob/release-2.0/pages/Module%20Resolution.md#path-mapping

@mhegazy mhegazy added the Duplicate An existing issue was already created label Apr 5, 2016
@microsoft microsoft locked and limited conversation to collaborators Jun 19, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Duplicate An existing issue was already created
Projects
None yet
Development

No branches or pull requests

3 participants