So, I ran into this nasty issue in the following situation:
- Multiple TypeScript projects
- Running Webpack (via Angular CLI) on web project
- npm linking from my web project to other local projects
- Common downstream dependencies that are referenced in multiple local projects such as rxjs, firebase, @angular/core, etc.
When I first tried to run Webpack (via the Angular CLI) in this situation it choked even though it worked fine without npm linking. Specifically, I got two types of errors/warnings:
// 1.
WARNING in ../some/path/here.js
(Emitted value instead of an instance of Error) Cannot find source file '/some/otherpath//here.ts'
// 2.
ERROR in /some/path/here.d.ts (6,22): Class 'Foo' incorrectly implements interface 'BaseFoo'.
Types of property 'someMethod' are incompatible.
Type '(blah: Blah) => Observable<SomeResponse>' is not assignable to type '(blah: Blah) => Observable<SomeResponse>'. Two different types with this name exist, but they are unrelated.
Type 'Observable<SomeResponse>' is not assignable to type 'Observable<SomeResponse>'. Two different types with this name exist, but they are unrelated.
Property 'source' is protected but type 'Observable<T>' is not a class derived from 'Observable<T>'.
So, the second issue was a little more easily resolved because of this long thread on the TypeScript repo: microsoft/TypeScript#6496
The solution for the second issue involved two things. First, I had to upgrade to version 1.1.0-rc.2 of the Angular CLI which has some webpack changes to address this very issue. Second, I added the following to the compilerOptions
in my UI project's tsconfig.json:
"paths": {
"firebase": ["../node_modules/firebase"],
"rxjs": ["../node_modules/rxjs"],
"rxjs/*": ["../node_modules/rxjs/*"],
"@gethuman/*": ["../node_modules/@gethuman/*"],
"@angular/*": ["../node_modules/@angular/*"]
},
The first issue was a little trickier. The key, though, was that it clearly didn't have the right path to the source TypeScript file. It turned out that the problem was in the tsconfig.json files of all the linked projects (i.e. not in the UI project). In each of those projects I had this in the tsconfig.json:
"sourceRoot": "",
All generated source maps have a path back to the original source file, but with this setting, the path to the source file was incorrect.
Instead of something like /path/to/../../the/file.ts
it would be something like /path/to//the/file.ts
. The solution was simply removing
sourceRoot
from all my tsconfig files and letting TypeScript do it's thing to set the path correctly when the source map is generated.
Whew...that was like 6 hours of my life so hopefully this can help someone else who runs into the same issue. The silver lining is that I learned a shitload about how TypeScript, Webpack and the Angular CLI work in the process of debugging this.