Typescript: Resolving hoisted `typeRoots` paths

Created on 1 Sep 2019  Â·  5Comments  Â·  Source: microsoft/TypeScript


TypeScript Version: 3.6.2


Search Terms:

  • resolve typeRoots in parent package node_modules
  • sharing tsconfig in yarn workspaces
  • use hoisted tsconfig in child package

Code

I've set up a Lerna monorepo which uses Yarn Workspaces. Within this monorepo is a config package, which other packages depend on. This config package has @types/node and @types/jest as dependencies.

From sibling packages, the shared config is used like so:

{
  "extends": "@project/config/ts.json",
  "include": ["src", "tests"],
  "compilerOptions": {
    "outDir": "lib"
  }
}

In the shared config, I point to the appropriate types root:

{
  "compilerOptions": {
    // ...
    "typeRoots": ["node_modules/@types"]
  }
}

However, within the shared config package, @types/* have been hoisted from the local node_modules to the monorepo's top-level node_modules. This behavior is usually fine given node's resolution... but it seems the config does not resolve to its parent's node_modules.

Expected behavior:

For the specified type root to resolve to the parent's node_modules

Actual behavior:

Tests fail with messages such as Cannot find name 'describe'. Do you need to install type definitions for a test runner? ...

One workaround:

{
  "compilerOptions": {
    // ...
    "typeRoots": ["../../node_modules/@types"]
  }
}

This workaround isn't very clean. Lerna & Yarn definitely pose some complexity for type root resolution. Hopefully resolving parents is considered a worthwhile modification.

Please let me know. Thank you :)

Needs Proposal Suggestion

Most helpful comment

This is one that we had been resolving with a workaround similar to the one that @harrysolovay proposes. Unfortunately, we quickly ran into an issue there with different versions of a @types package. Our particular situation was the internal-package-a had a dependency on @types/[email protected] where another had one on @types/[email protected]. This led to a case where in internal-package-a both node_modules and ../../node_modules(at the monorepo root) had a copy of @types/node, and was causing build failures.

We've managed to resolve this for the short term by homologating our versions of this type package, but I can see the day coming where we won't be able to do that and it'll lead to a crufty, byzantine set of tsconfig rules that expect certain packages in the package root versus the monorepo root (which is exactly the sort of thing we're looking to avoid).

Very much looking forward to some positive movement on this issue.

All 5 comments

Hmm, it seems like the extends is just copying the shared config into the local config verbatim, the path resolver must not even realize the path is supposed to be relative to the root tsconfig...

Hm. If I had to guess, this is by design, but definitely frustrating for your use case.

I’m having the same issue, but in my case I can’t change the typeRoots in the package, which specifies node_modules/@types.
One workaround I found for now is to explicitly tell yarn about the packages that don’t work with hoisted modules, by adding the “nohoist” property to the “workspaces”-object. It works, in the sense that the packages now have their own node_modules folder, but I’d much prefer it if typescript could figure out where the node_modules folder actually is.

This is one that we had been resolving with a workaround similar to the one that @harrysolovay proposes. Unfortunately, we quickly ran into an issue there with different versions of a @types package. Our particular situation was the internal-package-a had a dependency on @types/[email protected] where another had one on @types/[email protected]. This led to a case where in internal-package-a both node_modules and ../../node_modules(at the monorepo root) had a copy of @types/node, and was causing build failures.

We've managed to resolve this for the short term by homologating our versions of this type package, but I can see the day coming where we won't be able to do that and it'll lead to a crufty, byzantine set of tsconfig rules that expect certain packages in the package root versus the monorepo root (which is exactly the sort of thing we're looking to avoid).

Very much looking forward to some positive movement on this issue.

Hi! Has there been any changes regarding this issue by any chance? :)

I had to shoot "../../node_modules/@types", "./node_modules/@types" too

Was this page helpful?
0 / 5 - 0 ratings

Related issues

siddjain picture siddjain  Â·  3Comments

dlaberge picture dlaberge  Â·  3Comments

blendsdk picture blendsdk  Â·  3Comments

CyrusNajmabadi picture CyrusNajmabadi  Â·  3Comments

kyasbal-1994 picture kyasbal-1994  Â·  3Comments