Repository: TypeScript
Issue: Allow Intellisense autocomplete for star imports, for specific source files in your repository
Labels: Suggestion,Experience Enhancement

## 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 called `apiTypes.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:

```ts
// apiTypes.ts
export interface User {
  name: string;
}
```

```ts
// fooComponent.ts
import * as apiTypes from "./path/to/apiTypes.ts";

interface Props {
  user: apiTypes.User;
//      ^^^^^^^^^^^^^
}
```

To be clear, the specific request here is:

- Typing the symbol name `User` and then invoking intellisense would include an option to star-import the module `import * as apiTypes from "…";`, and then to insert the fully-qualified name `apiTypes.User`
    - `user: User|` -> `Ctrl+Space`  -> `[ ] apiTypes.User                 path/to/apiTypes` -> `Enter`
- Typing the text `apiTypes` and then invoking intellisense would include an option to star-import the module `import * as apiTypes from "…";`, leaving your cursor as-is so you could then type a period `.` and see module members
    - `function 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:

1. For a given module, it's extremely helpful for its import occurrences to be consistent (`* 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` vs `import * as apiTypes` vs …)
     - Telling developers "oh, you should import this file this way, but other files this other way" is brittle in practice
     - While I understand there are other ways to solve this problem, like lint rules + refactorings, it really breaks the devX flow when you hit a symbol like `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.
1. The use-case that I'm really modeling this request around is for modules that describe an API. I'd love to be able to write code that _looks_ like `resourceApi.Resource` vs `energyApi.Resource`.
     - One alternative is to prefix all symbols in the module, like `ResourceApiResource` or `ResourceApi_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 developers
1. You can accomplish something almost equivalent using TypeScript `namespace`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. 
      - The runtime tree-shaking/dead-code-removal aspect is important for things like an Icons file or http endpoints files where you wouldn't necessarily want your final bundle to package all of the symbols.
      - Namespaces like this don't allow autocomplete when importing their members, like `Resource|` -> `Ctrl+Space` to pull up `energyApi.Resource`. You'd first have to `energyApi` -> `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 as `apiTypes.User` instead of the named `{ User }` import.

```ts
// apiTypes.ts
/** @preferNamespaceImport apiTypes */

export interface User {
  name: string;
}
```

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 codebases

## Past 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

- https://github.com/microsoft/vscode/issues/37258
- https://github.com/microsoft/TypeScript/issues/19630
- https://github.com/microsoft/TypeScript/issues/48297
- https://github.com/microsoft/TypeScript/issues/23830

## 🔍 Search Terms

Star imports, namespace, intellisense, autocomplete

## ✅ Viability Checklist

My suggestion meets these guidelines:

* [x] This wouldn't be a breaking change in existing TypeScript/JavaScript code
* [x] This wouldn't change the runtime behavior of existing JavaScript code
* [x] This could be implemented without emitting different JS based on the types of the expressions
* [x] This isn't a runtime feature (e.g. library functionality, non-ECMAScript syntax with JavaScript output, new syntax sugar for JS, etc.)
* [x] This feature would agree with the rest of [TypeScript's Design Goals](https://github.com/Microsoft/TypeScript/wiki/TypeScript-Design-Goals).