TypeScript icon indicating copy to clipboard operation
TypeScript copied to clipboard

tsc not respecting types/typeRoots config for imported modules

Open danprince opened this issue 4 years ago • 9 comments
trafficstars

Bug Report

Codebase is pulling in type declarations from the parent ../node_modules/@types/ folder, despite attempting to restrict the types and typeRoots to ignore it.

client/
  node_modules/@types/foo/ # server shouldn't ever see this!
  tsconfig.json
  
  server/
    node_modules/foo/ # server should see this as a module with no type declarations
    tsconfig.json

🔎 Search Terms

  • Stop typescript from including types from parent node_modules
  • Prevent typeRoots from using parent node_modules

Related Issues:

  • How to block typescript 2.0 from walking up all parent directories while resolving modules? #13992
  • Declarations are unexpectedly used from node_modules in parent directory #30124

The issue is very similar to the ones described above, but neither were resolved beyond saying that unwanted types could be excluded with "types": []. This only seems to work for excluding global types (e.g. @types/node) as far as I can tell, there is no way to prevent typescript pulling in types for a module that is explicitly imported. See repro for more context.

🕗 Version & Regression Information

We are seeing this problem with [email protected], but I have created a reproduction that also confirms it on typescript@latest and typescript@next too.

  • This is the behavior in every version I tried, and I reviewed the FAQ for entries about excluding types and type roots.

💻 Code

Reproduced in repo with CI demonstrating incorrect behaviour here: https://github.com/danprince/typeroots-bug-repro

🙁 Actual behavior

The server codebase ends up including ../node_modules/@types/foo/index.d.ts as part of the compilation (through an import foo from "foo") even with "typeRoots": ["./node_modules/@types"] and "types": [].

Our current workaround is to remove the parent node_modules as part of our CI step.

We could also work around this by shadowing the declarations in the local node_modules/@types dir, or using paths hack to point typescript towards a non-existent version of the module, but it shouldn't be that hard.

All I want is to tell tsc is to never ever look in ../node_modules/@types.

🙂 Expected behavior

Never look in ../node_modules/@types for anything. I know that conflicts with the "moduleResolution": "node" to some degree, but it should be possible to configure that as far as type declarations are concerned.

danprince avatar Mar 05 '21 11:03 danprince

This is the intended behavior of module resolution. If other people encounter this with some frequency we could think about some new option to change module resolution, but it'd be a new switch of some kind.

RyanCavanaugh avatar Mar 05 '21 19:03 RyanCavanaugh

Understood. Thanks!

Our use case here is probably too specific to ever be worth changing the module resolution behaviour, but I could definitely see it being worth an additional note in the docs.

I had been thinking that the general concept of the node_modules/@types directory was fully configurable with typeRoots, rather than being a distinct part of module resolution.

danprince avatar Mar 07 '21 22:03 danprince

Is there a workaround? Or is the solution never to nest projects?

flpvsk avatar Jun 02 '21 19:06 flpvsk

I am also looking for a solution here. I have two nested projects, and the nested one tries to look in ../node_modules/@types instead of resolving from its own node_modules/@types folder.

NoMercy235 avatar Jul 14 '21 08:07 NoMercy235

Bumping this, we've also encountered this issue. it had the effect of a parent module in ../node_modules/@types causing tsc --noEmit for child projects to pass in CI (not only was the missing package error not shown, the actual compilation errors did not appear either). This caused code to be deployed our servers, to which it promptly died upon compilation.

Forgive my nativity around how TS handles module resolution; If we can't change the behavior, would it be possible to have a warning of some kind that typeRoots is being ignored and that type modules are still being consumed from the parent by the child project? Or maybe just a documentation update around typeRoots? The way it's written right now implies this shouldn't be possible.

Outside of the silent failure from tsc --noEmit which may be another issue, this would have at least pointed us towards a solution a lot quicker.

We also went for removing the parent ../node_modules/@types before running tsc --noEmit as our work-around.

off-by-some avatar Mar 29 '22 19:03 off-by-some

It appears to me (I don't have a convenient isolated test case) that the problem from multiple past issues still exists also: TypeScript looks up to ../node_modules/@types/ for global types, no matter what combination of typeRoots, types, etc. is configured. It's a significant problem with manually or automatically hoisted dependencies in a monorepo.

kylecordes avatar Jun 09 '22 19:06 kylecordes

Isn't this behavior directly contradicts typeRoots documentation ,which states If typeRoots is specified, only packages under typeRoots will be included ?? If this documentation is incorrect and behavior is expected, maybe at least documentation should be changed, stating that 'only packages under typeRoots will be included and also everything that falls under ../node_modules/@types, etc , etc'?

Just tried configuring both "types": [] and "typeRoots": [] - got ../node_modules/@types included still. Quite counterintuitive and definitely misleading in documentation

strowk avatar Apr 12 '23 13:04 strowk

I’ve been hit by this problem as well. In my case I just wanted to turn of resolution of node_modules/@types completely, which should be possible according to the documentation. So i’ve set typeRoots to an empty array, but this doesn’t have any effect.

lo1tuma avatar Jan 29 '24 16:01 lo1tuma

This is a real pain for monorepo DX — it's impossible to get realtime feedback in IDE or in a development environment due to this issue.

I've had to resort to rm -rf ../node_modules on CI, but that's not realistic on a dev machine during every day dev work.

TSMMark avatar Jun 11 '25 16:06 TSMMark