Typescript: Provide a means for mapping back to .ts files in published packages

Created on 28 Jun 2017  路  11Comments  路  Source: microsoft/TypeScript

We have a mono repo with many small npm packages in it.
All of them share the same configuration in which we keep the *.ts files in a src folder and let tsc emit the *.js and *.d.ts to a lib folder.

For relative paths within a package tsc nicely resolves against the local source (*.ts) but for references across packages it resolves against the type definitions, because we use imports like:

import foo from "otherpackage/lib/module"

This makes navigation in code (find references, etc.) useless. Could the paths property in the compiler options, allow something like the following, so that tsc would resolve against the actual source?

   "paths" : {
      "*/lib/*" : ["*/src/*","*/lib/*"]
   }

Or is there another (better) way to deal with this?

Declaration Emit In Discussion Monorepos & Cross-Project References Suggestion

Most helpful comment

We figured out a way to make it work, by using two different tsconfigs in monorepo (we use lerna). One for VS Code (resolving against *.ts), one for the build (resolving against *.d.ts).
You can have a look here : https://github.com/theia-ide/theia

All 11 comments

If you are publishing a package to NPM it is best to make it so that users don't need to specify path mapping. Maybe you could compile using the --declaration option?
See the handbook on publishing.

There's a proposal for go-to-implementation in .js files at #6209, but I think you want that for the .ts files. One potential idea is using source-maps when available.

@DanielRosenwasser I don't see how this is related to that? This is a compile error (assuming --noImplicitAny is on and you resolve to the .js location instead of the .ts location), not a services issue.

I'm not sure what you mean. My understanding is that the request here is to provide a way to re-map the runtime import to the .ts source. Specifically, this sentence:

This makes navigation in code (find references, etc.) useless.

@svenefftinge can you confirm?

Ah, I was focusing on the path mapping part. So it sounds like the current compile-time behavior of getting the .d.ts file is fine, but in services it would be nicer to go to the .ts file.
Path mapping would change the compile behavior too, of course. That is probably a good thing -- it could be confusing if something was a type error when compiling but not in services, or vice versa.

Just a thought: It might make sense for a package to be published simply as lib with .js files and src with .ts files, and no .d.ts files anywhere. The compiler could use a new kind of value for "types" in package.json to know to resolve imports foo/lib/a.js to foo/src/a.ts.

One of the downsides of that approach is that a full type-check takes much longer and memory consumption grows a lot more for a project of .ts files than its .d.ts counterparts. But I guess you'd still potentially have those problems if you supported any of these scenarios.

I would want tsc to link against the *.ts instead of the ts.d. So that language services work better across node packages.

Regarding the memory consumption, it would be nice if tsc doesn't check bodies if the signatures are complete (have return type) and the file is not part of the include.

I actually managed to do what I want using the current paths semantics. I basically have to put in a path mapping for every of my projects. So a bit inconvenient, but it works :)

I think the main request is for IDE's to be able to find the implementation done in the .ts files when you have included a library. E.g. Visual Studio 2017 can only show the definition (F12) and jumps to the .d.ts file, but there is no (easy) way to go to the original .ts file, where things were implemented (e.g. if several TS files have been combined into one js. and d.ts file using the --output option. I assume the source maps have all the info to enable you to jump to the right .ts files instead of just the .d.ts file. Right now it seems impossible to arrange a project / solution consisting of multiple projects that each produce an combined .js output and then find your way around easily in the whole solution using the "go to declaration" and "go to implementation" features.

We figured out a way to make it work, by using two different tsconfigs in monorepo (we use lerna). One for VS Code (resolving against *.ts), one for the build (resolving against *.d.ts).
You can have a look here : https://github.com/theia-ide/theia

I was encountering the same problem, where we used path mapping in dev, and lost typing information with the published package

Was this page helpful?
0 / 5 - 0 ratings