Skip to content

exports/dead-export analysis never counts consumers of TypeScript interfaces/type aliases #1833

Description

@carlos-alm

While implementing #1733 I hit what looks like a real gap in codegraph's own `codegraph exports`/dead-export detection (the same query the `pre-commit-checks.js` hook uses to block commits that add unused exports).

Repro (no code changes needed — reproduces on pre-existing code):

codegraph exports src/types.ts -T

Output includes:

I LanguageRegistryEntry [core] :778
  (no consumers)

But `LanguageRegistryEntry` is definitely consumed:

Despite these, `codegraph exports` reports zero consumers. I confirmed this isn't specific to `import type` syntax — the re-export in parser.ts uses `export type { ... } from`, and the direct generic-parameter usage (`LanguageRegistryEntry[]`) in the same file also doesn't register as a consuming reference.

Hypothesis: the exports/dead-export consumer-counting logic only tracks value-level (function/const/class) call-graph edges and has no mechanism for attributing "used as a type annotation / generic parameter elsewhere" back to an interface or type-alias declaration as a consumer relationship.

Impact: any interface or type alias in the codebase that is only ever referenced in type position (which is normal/expected for most interfaces) will always show as a "dead export," even when genuinely used everywhere. This makes `codegraph exports`/the pre-commit dead-export gate unreliable for interfaces and type aliases specifically — currently it can only be trusted for value-level exports (functions, consts, classes).

Not fixing inline as part of #1733 — that issue is scoped to environment/doctor tooling, and this is a separate, pre-existing gap in the symbol-resolution/exports subsystem (likely `domain/analysis/exports.ts` and/or the graph-model consumer-counting logic, possibly needing changes in both the native and WASM engines per the dual-engine parity requirement). Worked around it in #1733's own new module by not exporting types that had no non-test value-level consumer, per the pre-commit gate's current (buggy) verdict — but that gate should ideally be fixed so future contributors don't have to make the same workaround for legitimately-useful exported types.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions