Expand auto-import to all dependencies in package.json · Issue #37812 · microsoft/TypeScript (original) (raw)
Background
TypeScript's auto-import functionality has some really unpredictable behavior today where the feature doesn't work on for a package until a user manually imports from that package. This experience only affects projects that provide their own types because, by default, TypeScript always includes @types
packages as part of every compilation; however, it doesn't include other packages in node_modules
[1]. Apart from being unfair to TypeScript library authors, this is just plain surprising for users.
For a while now, we've received consistent feedback that this is a confusing experience.
- VSCode Angular 9 Auto-Import for Custom Libraries #37222
- Auto import in angular typescript is not working #28773 (comment)
- Auto Import not working with node_modules #30033
- Can't use auto import when node_modules are named "node_modules" #29629
- Auto import in angular typescript is not working #28773
- Auto-imports from builder-util-runtime #38176
- https://twitter.com/alephnaught2tog/status/1245026801564467203
Additionally, we've been seeing weird hacks in projects like Angular CLI, where typeRoots
are set to node_modules
and node_modules/@types
to try to fix auto-imports.
Proposal
In #31893 and #32517, we improved some rough areas of completions by making sure that we only provided completions from packages that are listed in package.json
. That way clearTimeout
doesn't appear in your completion list unless you specifically list @types/node
as a dependency.
What I'd like to suggest is an expansion of completions sources to those in package.json
. Specifically what I'm looking for is that for every dependency in package.json
, we should try to provide auto-imports. This could be done by changing the default behavior for typeRoots
(potentially breaking) or by adding an editor-specific behavior for automatic package inclusion.
There's things to keep in mind as we do this:
- we don't want to accidentally load up 100s of
.d.ts
files unnecessarily - we don't want to have duplicate entries when a package ships its own
.d.ts
files but a user has@types
packages installed - we don't want to add new logic that affects module resolution and changes the behavior of go-to-definition
- we don't want to drastically diverge in behavior from the command-line
Maybe for the general case, this won't cause a drastic increase in memory usage - most packages with explicit dependencies might get installed/eventually used anyway. But if it is, there might be some workarounds to consider:
- only go through 2-3 levels of imports for these expanded completions
- this might not work well for "barrels" (i.e. files with a lot of
export * from
statements), but it might just be good enough.
- this might not work well for "barrels" (i.e. files with a lot of
- only expand auto-completions to
dependencies
and notdevDependencies
- this would be really confusing for utilities and test code, but not application code.
I'd like to get people's thoughts on whether an approach like this would even be possible, and if so, whether we could implement it without degrading the current experience.
[1] The reason for this is the asumption that having an @types
package in your node_modules
directory is a pretty good sign that you intend to use it (with caveats - see #31893 and #32273). But in order to save on time/memory, we don't load up .d.ts
files from other node_modules
packages unless we really need to.