Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Auto-importing modules as namespaces? #23830

Closed
rauschma opened this issue May 2, 2018 · 25 comments
Closed

Auto-importing modules as namespaces? #23830

rauschma opened this issue May 2, 2018 · 25 comments
Labels
Declined The issue was declined as something which matches the TypeScript vision Domain: Completion Lists The issue relates to showing completion lists in an editor Domain: Quick Fixes Editor-provided fixes, often called code actions. Suggestion An idea for TypeScript

Comments

@rauschma
Copy link

rauschma commented May 2, 2018

I’m not sure what the best way is to fix this, but: auto-importing is incredibly helpful. Alas, it only works for named exports. However, imports such as the following are frequent in Node.js and there, you get no help:

import * as path from 'path';

Possible solution: offer an auto-import if:

  • there is an unknown foo followed by a dot and
  • foo is the base name of a module.
@RyanCavanaugh
Copy link
Member

Can you clarify what you're typing and when you'd expect this to show up?

@rauschma
Copy link
Author

rauschma commented May 2, 2018

  • Typing: path. (path being an unknown identifier).
  • Quick fix suggestion: auto-import 'path'.

But I’m open to anything that helps with import * as: maybe there doesn’t have to be a dot after path. Then auto-importing would be offered for both namespace imports and named imports.

@ghost
Copy link

ghost commented May 2, 2018

If something is already imported as a namespace, we ought to (but don't currently) prefix a completion with the namespace name, rather than adding a new named import.

As a second issue we might consider adding an option to always make a namespace import even if one doesn't already exist.

@ghost ghost added Domain: Completion Lists The issue relates to showing completion lists in an editor Suggestion An idea for TypeScript labels May 2, 2018
@rauschma
Copy link
Author

rauschma commented May 2, 2018

As a second issue we might consider adding an option to always make a namespace import even if one doesn't already exist.

I don’t think that that would be useful:

  • With path, both named imports and namespace imports are common.
  • My thinking usually starts with: “something in module path”. Therefore, I’d prefer it if an IDE would namespace-import path for me when I first mention its name.

@mhegazy
Copy link
Contributor

mhegazy commented May 3, 2018

So the suggestion here is to offer the names of modules in the completion list with an additional action to import them? i.e. path would show up as a completion entry in the global scope.

@rauschma
Copy link
Author

rauschma commented May 3, 2018

Yes! But I’m not sure what you mean by “in the global scope”. path would be global-ish, but the suggestion would appear anywhere, independent of scope.

@rauschma
Copy link
Author

rauschma commented May 3, 2018

Oh, and it could be complemented by a quick fix offering to namespace-import path whenever that identifier is ever unknown anywhere.

@mhegazy mhegazy added the Domain: Quick Fixes Editor-provided fixes, often called code actions. label May 3, 2018
@mhegazy
Copy link
Contributor

mhegazy commented May 3, 2018

My only worry is the amount of unrelated names we put in the completion list.

@DanielRosenwasser
Copy link
Member

My only worry is the amount of unrelated names we put in the completion list.

True, but we already add in every possible named export in a project context.

@DanielRosenwasser DanielRosenwasser added Domain: Quick Fixes Editor-provided fixes, often called code actions. and removed Domain: Quick Fixes Editor-provided fixes, often called code actions. labels May 4, 2018
@weswigham weswigham added Needs Proposal This issue needs a plan that clarifies the finer details of how it could be implemented. In Discussion Not yet reached consensus labels Nov 6, 2018
@DanielRosenwasser
Copy link
Member

This just gets very annoying for anything in Node that's a built-in. path, fs, and more are just painful to import. otherwise. Maybe when moduleResolution is calculated as node, we could try

  • All non-globbed ambient module declarations with no slashes.
  • All dependent packages in package.json that have a declaration

@RyanCavanaugh RyanCavanaugh added Awaiting More Feedback This means we'd like to hear from more people who would be helped by this feature and removed In Discussion Not yet reached consensus Needs Proposal This issue needs a plan that clarifies the finer details of how it could be implemented. labels Mar 7, 2019
@OliverJAsh
Copy link
Contributor

OliverJAsh commented Aug 8, 2019

Issue related to this: #19630

Perhaps TS could suggest namespace imports based on existing imports in the project?

E.g. if the module foo/bar is imported as …

import * as FooBar from 'foo/bar';

… in other modules, then when I type FooBar in this module, suggest importing it using the same import statement as seen in other modules (above). TS would learn from how the same module is imported elsewhere.

@mikecann
Copy link

mikecann commented Jan 9, 2020

Has there been any movement on this? I noticed that VS code now sometimes adds a bracketed name to the module name where the imported function is coming from..

@DanielRosenwasser
Copy link
Member

My only worry is the amount of unrelated names we put in the completion list.

Maybe we could we limit this to ambient module declarations, and packages listed in dependencies, devDependencies, and peerDependencies?

@DanielRosenwasser DanielRosenwasser added Help Wanted You can do this Effort: Moderate Requires experience with the TypeScript codebase, but feasible. Harder than "Effort: Casual". and removed Awaiting More Feedback This means we'd like to hear from more people who would be helped by this feature labels Feb 24, 2020
@DanielRosenwasser DanielRosenwasser added this to the Backlog milestone Feb 24, 2020
@andrewbranch
Copy link
Member

Maybe we could we limit this to ambient module declarations, and packages listed in dependencies, devDependencies, and peerDependencies?

That would happen automatically at this point: #32517

@DanielRosenwasser
Copy link
Member

So really the concerns are pretty limited at this point - would the main thing here be to just grab the list of ambients and dependencies and ensure that in the completion list their names

  • are camel-cased (bar-baz becomes barBaz)
  • don't include the namespaced portion (e.g. @foo/bar-baz becomes barBaz)

@andrewbranch andrewbranch added this to the TypeScript 4.4.0 (Beta) milestone Jun 7, 2021
@andrewbranch andrewbranch self-assigned this Jun 7, 2021
@andrewbranch andrewbranch removed Effort: Moderate Requires experience with the TypeScript codebase, but feasible. Harder than "Effort: Casual". Help Wanted You can do this labels Jun 7, 2021
@andrewbranch
Copy link
Member

I think the latter suggestion is too complex/expensive, but the rest of these cases seem like they should be an easy fix.

@OliverJAsh
Copy link
Contributor

@andrewbranch Perhaps VS Code could provide an API so extensions can contribute import suggestions (which appear in the suggestions drop down when typing and as quick fixes), then someone could write an extension to do this. Do you know if anything like that exists?

@andrewbranch andrewbranch added the Rescheduled This issue was previously scheduled to an earlier milestone label Jul 6, 2021
@andrewbranch andrewbranch removed this from the TypeScript 4.6.1 milestone Feb 8, 2022
@andrewbranch andrewbranch removed their assignment Feb 8, 2022
@andrewbranch
Copy link
Member

andrewbranch commented Feb 8, 2022

I’ve looked into this a good bit and decided I don’t want to do it in general. We can’t know the conventions by which the namespace export is named: path comes from "path" but React comes from "react". It would be super annoying when we inevitably get a convention wrong.

I investigated this:

This works for path but not for other things like url or querystring. Do you know why?

The "path" module typings declare an export = path and we pull the name from the declaration of the symbol being exported. On the other hand, the "url" module (along with the majority of node built-ins) has no export = declaration; it’s simply a collection of named exports. These named exports could be wrapped in a namespace named url and then export = url from the top level. The module would behave almost identically to the way it behaves as written today, except that export * from "url" would become an error. It’s worth noting that some of the node built-ins like path and assert are written as an export = out of necessity or convenience, and export * from "path" is already an error because of that, despite it being valid in Node. It could be worth making the change to the rest of the modules to allow auto-imports to work better. This is a question for the Node typings maintainers to consider on DefinitelyTyped.

@OliverJAsh’s suggestion of picking up on namespace import names used elsewhere in the program is probably the only solution here that can provide a decent UX, but I think it’s too much complexity for the value it delivers. (It would be too expensive to look up these associations from other files on demand when we’re generating a completions list, so we’d have to introduce a new cache, which means you have to think about cache invalidation.)

Perhaps VS Code could provide an API so extensions can contribute import suggestions (which appear in the suggestions drop down when typing and as quick fixes), then someone could write an extension to do this. Do you know if anything like that exists?

As far as I know, these APIs are separate, but there is nothing stopping a single extension from sharing code to contribute to both APIs.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Declined The issue was declined as something which matches the TypeScript vision Domain: Completion Lists The issue relates to showing completion lists in an editor Domain: Quick Fixes Editor-provided fixes, often called code actions. Suggestion An idea for TypeScript
Projects
None yet
Development

No branches or pull requests

9 participants