typescript-eslint / typescript-eslint/ts-api-utils

🐛 Bug: getDeclarationDomain treats type-only imports as value+type

Open
#1,054 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

type: bug
Dominant language
TypeScript
Stars
122
Forks
17
PR merge metrics
No merged PRs in 30d

Description

Bug Report Checklist
  • I have tried restarting my IDE and the issue persists.
  • I have pulled the latest main branch of the repository.
  • I have searched for related issues and found none that matched my issue.
Expected

Type-only import bindings should be classified as type-only.
For example, these should return DeclarationDomain.Type | DeclarationDomain.Import:

  • import type { Foo } from "./mod"
  • import { type Foo } from "./mod"
  • import type Foo from "./mod"
  • import type * as NS from "./mod"
  • import type TypeEquals = require("./mod")
    Value imports such as import { Bar } from "./mod" should keep DeclarationDomain.Any | DeclarationDomain.Import.
Actual

getDeclarationDomain always returns DeclarationDomain.Any | DeclarationDomain.Import for ImportClause, NamespaceImport, ImportSpecifier, and ImportEqualsDeclaration names. It does not check isTypeOnly.

That makes a type-only import look like it also exists in the value and namespace domains. collectVariableUsage inherits the same domain because UsageWalker currently hardcodes Any | Import for import declarations.

There is an existing comment in src/usage/declarations.ts:
// TODO handle type-only imports
This was carried over from tsutils and never implemented.

Additional Info

I searched open and closed issues for getDeclarationDomain, DeclarationDomain, collectVariableUsage, and “type-only import”. I did not find an existing report of this bug.
Related but different: #263 ported collectVariableUsage from tsutils (including this TODO). It did not ask to handle type-only imports.
Minimal reproduction:

import type { Foo } from "./mod";

Relevant files:
- `src/usage/declarations.ts` — `getDeclarationDomain` (`ImportClause`, `NamespaceImport`, `ImportSpecifier`, `ImportEqualsDeclaration`)
- `src/usage/UsageWalker.ts` — import declarations are recorded as `Any | Import`
- `src/usage/collectVariableUsage.ts` — public API that surfaces that domain
There are no tests today for `import type` / inline `type` specifiers.

🥨

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in src/usage/declarations.ts at getDeclarationDomain and trace the import cases listed in the issue. Then read import handling in src/usage/UsageWalker.ts and the public flow through src/usage/collectVariableUsage.ts. Done means the listed type-only forms report Type | Import, value imports retain Any | Import, and coverage exists for these cases.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
tooling
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
74/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.