-
Notifications
You must be signed in to change notification settings - Fork 12.8k
Allow Intellisense autocomplete for star imports, for specific source files in your repository #49895
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
Comments
There's a little confusion here because we actually have two features:
Things I like about this:
Things I don't like:
|
Counterpoint, in a large code base there is a need for API names to be consistent and somewhat unique. Some backgroundConsider this example: import { combine } from './filePath.ts';
combine(x,y); Suppose that someone needs to search for all calls to the IntelliSense can help find references to
For these requirements, One solutionOur coding conventions strongly encourage a longer name such as import { FilePath } from './FilePath.ts';
FilePath.combine(x, y); We also encourage the longer name to include a container like So... what about this: import * as filePath from './filePath.ts';
filePath.combine(x, y); It is mostly a solution to the original requirements. But only if we include an ESLint rule to enforce that the identifier import * as fp from './filePath.ts';
fp.combine(x, y);
import { combine } from './filePath.ts'; Doing so would thwart our ability to search for A requestIt's great for QuickFix to provide better support for people who prefer |
@octogonz all of that granted, the solution to the problem you're describing is a lint rule, not a nudge from auto-import/quickfix |
@RyanCavanaugh respectfully, I disagree: You're able to write For one the reasoning behind this notion has never been clear imho and in practice this is not an issue. E.g. a package uploaded to NPM must have a unique name already, library authors already have to think about a unique "root identifier" for their code. Up until here you're right - this can be done with a lint rule. But it still means that devs have to manually write star imports while not having to manually write qualified imports. This favors qualified imports which - in contrast to namespaced imports - is much more likely to lead to naming conflicts. This issue is currently handled by defining relations between code bits in file structure which is largely unchecked and brittle and including the relations in the name of each exported code bit, leading to names that have long been turned to memes regarding e.g. Javas So the issue at hand can be supported by lint rules but to actually turn the tides a deeper tooling integration would be needed. I really like your two "in favor" points above, can we please have that? Also, I'm wondering... don't you have people on the team that are deeply involved in F#? What do they have to say about this? Nesting, extending and opening modules has never been easier and safer for me than in F#, I'd really like to see some similar solutions in Typescript. |
Problem statement
Hey TypeScript team, I've huge respect for the software you've created for the community. I'd like to submit a request for some mechanism that improves the developer experience when trying to
import * as
for a module in your own codebase that you control. For example, if I have a file calledapiTypes.ts
, for there to be a mechanism that hints to VSCode that within this codebase, you'd prefer to import this file using star-imports (import * as apiTypes
) rather than a named import (import { User } from …
). In other words:To be clear, the specific request here is:
User
and then invoking intellisense would include an option to star-import the moduleimport * as apiTypes from "…";
, and then to insert the fully-qualified nameapiTypes.User
user: User|
->Ctrl+Space
->[ ] apiTypes.User path/to/apiTypes
->Enter
apiTypes
and then invoking intellisense would include an option to star-import the moduleimport * as apiTypes from "…";
, leaving your cursor as-is so you could then type a period.
and see module membersfunction foo(user: apiTypes|
->Ctrl+Space
->[ ] apiTypes path/to/apiTypes
->Enter
As somebody who has managed some very large codebases (1MM+ lines), the following observations are helpful for me to recognize:
* as foo from "./givenModule"
vs{ Named } from "./givenModule"
). It's likewise extremely helpful for the symbol used for its star-imports to be consistent (e.g.import * as api
vsimport * as apiTypes
vs …)User|
to either have to know you need to go add your own import by hand or using a snippet, or to eat that you're temporarily writing "nonconformant" code and to remember to run a refactoring, wait for a lint fixer, etc.resourceApi.Resource
vsenergyApi.Resource
.ResourceApiResource
orResourceApi_Resource
, but both lead to verbose-looking symbols that may be surprising for developers unfamiliar with your team's practices to understand what's going on at a glance. In contrast, star-imports are well-understood by developersnamespace
s, e.g.export namespace energyApi {}
, although it seems we're trying to move away from namespaces in practice, and they perform poorly RE: tree-shaking for runtime symbols.Resource|
->Ctrl+Space
to pull upenergyApi.Resource
. You'd first have toenergyApi
->Ctrl+Space
->Enter
->.R
->Enter
Suggestion
In an effort to simplify this problem and to be generative, how about a module-level
@pragma
directive to hint this behavior? For instance, the below top-of-file comment could be used by Intellisense to add an entry for this file, and all of its exports, to be imported asapiTypes.User
instead of the named{ User }
import.Said in different words, for files that contain a
@preferNamespaceImport
directive, Intellisense would choose to import those files using star-imports (using whatever symbol is specified in the pragma), rather than as destructured named imports.Naturally, this suggestion doesn't extend to third-party imports, like preferring lodash to be imported
* as lodash
or* as _
, etc. Again, this proposal isn't meant to be exhaustive, but in the codebases I've worked in, something like the pragma directive would go a long way to improving devX and encouraging consistent codebasesPast work and references
I recognize many iterations of this idea have been proposed in the past, so I'd like to link them here for completeness and to promote healthy discussion
🔍 Search Terms
Star imports, namespace, intellisense, autocomplete
✅ Viability Checklist
My suggestion meets these guidelines:
The text was updated successfully, but these errors were encountered: