Skip to content

Auto-import should not offer a barrel to files inside same packageΒ #64650

Description

@lonix1

πŸ” Search Terms

"typescript extension", "circular import", "barrel file", "autoImportFileExcludePatterns"

βœ… Viability Checklist

⭐ Suggestion

PROBLEM

Suppose a package exposes its public API through barrel files via exports subpaths. Within that package, auto-import offers the declaring file as well as the barrel. Accidentally choosing to import from the barrel from inside the package itself would create a circular import.

The autoImportFileExcludePatterns setting doesn't help. It matches the file being offered, not the importing file. So excluding the barrels would remove them for every importer, including consumers. (Doing so anyway means consumers would receive relative cross-project paths instead of the package subpath, and TS would report error 2878.)

REPRO

packages/shared/
  package.json            // "name": "@company/shared", "exports": { "./logging": "./src/api/logging.ts" }
  tsconfig.json           // composite, "module": "node20", rewriteRelativeImportExtensions
  src/api/logging.ts      // export * from '../logging/utils.ts';
  src/logging/utils.ts    // export function logEvent() {}
  src/other.ts
apps/billing/
  package.json            // "dependencies": { "@company/shared": "workspace:*" }
  tsconfig.json           // composite, "module": "node20", references: [{ "path": "../../packages/shared" }]
  src/index.ts
  1. In packages/shared/src/other.ts, type logEvent and request auto-import. Two suggestions appear: the declaring file and the ./api/logging barrel file.
  2. In apps/billing/src/index.ts, do the same. Two suggestions appear: the declaring file (as a relative cross-project path) and @company/shared/logging.
  3. Add setting "js/ts.preferences.autoImportFileExcludePatterns": ["**/packages/*/src/api/*.ts"].
  4. Repeat step 2. The only suggestion is ../../../packages/shared/src/logging/utils.ts, which reports error 2878 ("This import path is unsafe to rewrite because it resolves to another project...").

EXPECTED

Barrels should be offered to consumers, not to files inside the package that declares them.

Perhaps a new extension setting can configure that?

ACTUAL

Importers inside and outside the package are treated identically:

  • Without the setting, both are offered the barrel and the declaring file.
  • With the setting, neither is offered the barrel.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions