Skip to content

[api-extractor] Report unresolvable inline import paths in .d.ts rollups - #5925

Merged
Sean Larkin (TheLarkInn) merged 1 commit into
microsoft:mainfrom
MLuc24:fix/api-extractor-relative-import-path
Aug 21, 2026
Merged

[api-extractor] Report unresolvable inline import paths in .d.ts rollups#5925
Sean Larkin (TheLarkInn) merged 1 commit into
microsoft:mainfrom
MLuc24:fix/api-extractor-relative-import-path

Conversation

@MLuc24

Copy link
Copy Markdown
Contributor

Summary

Fixes #4507

Per Pete Gonzalez (@octogonz)'s conclusion on that issue — "Let's improve the error message: API Extractor could analyze the .d.ts output and identify import paths such as ../Bar that clearly don't make sense in a rollup, and report a more intuitive error message" — this adds a dedicated ae-unresolved-import-path message for that case.

Today an unresolvable inline import() type is emitted into the rollup verbatim. The generated .d.ts then contains a relative path that points nowhere, so it does not compile for consumers, and the only hint is an ae-forgotten-export warning that names the symbol rather than the real problem.

Details

In DtsEmitHelpers.modifyImportTypeSpan, everything happens under if (referencedEntity). When the entity lookup fails there is no else, so the span keeps its original text and the path survives into the rollup. The new else if inspects the import's module specifier and, when it is relative, reports the message against the same declaration.

The check is deliberately narrow: only a specifier starting with . is reported. A bare specifier that fails to resolve is a different situation (the rollup emits a real import for it), and the resolving case is untouched — see the negative test below.

Two choices I would be happy to change: the message id name ae-unresolved-import-path, and leaving it at the default warning severity rather than adding an entry to api-extractor-defaults.json. Say the word and I will adjust either.

I did not add a case under build-tests/api-extractor-scenarios, because I could not regenerate the committed expected outputs locally (see below). Happy to add one if you would like it in this PR.

How it was tested

Built the contrived example from the issue against @microsoft/api-extractor 7.58.12 — Bar.ts exporting an enum, foo/Foo.ts declaring export type Foo = import('../Bar').Bar.A;, and index.ts re-exporting Foo.

Before, the rollup silently ends up unusable:

$ npx api-extractor run --local
Warning: lib/foo/Foo.d.ts:1:1 - (ae-forgotten-export) The symbol "Bar" needs to be exported by the entry point index.d.ts
API Extractor completed successfully

$ cat out-rollup/rollup.d.ts
export declare type Foo = import('../Bar').Bar.A;

With this change applied, the cause is reported:

Warning: lib/foo/Foo.d.ts:1:1 - (ae-unresolved-import-path) The inline import path "../Bar" could not be resolved,
  so it would be emitted unchanged into the .d.ts rollup, where it does not resolve to anything.
  Import the symbol at the top of the file instead of using an inline import() type.

Negative test, to confirm it does not fire on inline imports that resolve normally — changing Foo.ts to export type Foo = import('../Bar').Bar;:

$ npx api-extractor run --local
Warning: ... (ae-forgotten-export) ...
API Extractor completed successfully          # no ae-unresolved-import-path

$ cat out-rollup/rollup.d.ts
declare enum Bar {
    A = "A"
}
export declare type Foo = Bar;

Both runs were performed by applying this change to the published package's compiled output, since I could not run the monorepo's own rush build locally. The API report in common/reviews/api/api-extractor.api.md was updated by hand for the same reason, so it is worth confirming in CI that it matches.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

When an inline import() type could not be resolved to a rolled up entity, its
span was emitted verbatim. A relative path such as import('../Bar') means
nothing next to the rollup, which does not preserve the original file layout,
so the emitted .d.ts does not compile and the only clue was an unrelated
ae-forgotten-export warning.

Such paths are now reported as ae-unresolved-import-path.
@MLuc24
Pham Manh Luc (MLuc24) force-pushed the fix/api-extractor-relative-import-path branch from d804098 to 70346d1 Compare August 18, 2026 06:33
@TheLarkInn
Sean Larkin (TheLarkInn) merged commit 8f57395 into microsoft:main Aug 21, 2026
7 checks passed
@github-project-automation github-project-automation Bot moved this from Needs triage to Closed in Bug Triage Aug 21, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Closed

Development

Successfully merging this pull request may close these issues.

[api-extractor] Better error message for inline "import('../Thing')" in rollups

3 participants