Skip to content

Write a library's type declarations with its bundle - #72

Merged
dannote merged 2 commits into
masterfrom
declarations
Oct 7, 2026
Merged

dannote merged 2 commits into
masterfrom
declarations

Conversation

@dannote

@dannote dannote commented Oct 7, 2026

Copy link
Copy Markdown
Member

Fixes #71. Depends on oxc 0.19 (elixir-volt/oxc_ex#8) and quickbeam 0.11.3.

mix volt.build --declarations / config :volt, declarations: true writes one <name>.d.ts per script entry beside its bundle, unhashed, for package.json's types.

How (Volt.Builder.Declarations): each module → OXC.isolated_declarations/3 (or the owning plugin's declaration/3, so .vue works through vize). The graph is walked along the declarations' imports via Volt.Builder.Resolver, so modules that only hold types are included. Then a dts bundle in the rollup-plugin-dts sense: only declarations reachable from the entry's exports are kept (plus ambient declare module/declare global), external imports are hoisted and deduped, project imports/re-exports/export * are resolved to the declaring module, same-named declarations in different modules get $1, $2 (nearest the entry keeps its name), and one export { ... } list closes the file. Rolldown 1.1 has no .d.ts module type, so the bundling is Volt's own over OXC ASTs.

Verified on phoenix_replay's client (the issue's case, with the one replayMetadata annotation it needs): the bundle passes tsc --strict, and a type-level check against tsc's own 10-file --declaration output shows identical export sets and compatible types. 31 modules in ~2 ms.

Errors: an exported declaration without explicit types fails the build with the module path and TS9007/9010-style diagnostics; import * as / export * as of project modules and anonymous export default are reported as unsupported.

Tests cover reachability, re-exports and aliases, export *, external hoisting, JSDoc, renaming, Vue components, the error paths, and the build integration (single and multi-entry ESM).

mix volt.build --declarations writes one <name>.d.ts per entry beside
its bundle, without a hash. Volt.Builder.Declarations emits each module
through OXC's isolated declarations, or the plugin that owns it, then
bundles them as rollup-plugin-dts does: it walks the graph along the
declarations' own imports so types-only modules are included, keeps the
declarations the entry's exports reach and the ambient ones, hoists
imports of other packages, and renames same-named declarations of
different modules. Requires oxc 0.19 and quickbeam 0.11.3.

Fixes #71
@dannote
dannote merged commit 6ab438c into master Oct 7, 2026
2 checks passed
@dannote
dannote deleted the declarations branch October 7, 2026 22:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Write type declarations for library builds, one .d.ts per entry

1 participant