Skip to content

feat: add typescript type declarations for analyzeCommits - #961

Open
Mearman wants to merge 1 commit into
semantic-release:masterfrom
Mearman:feat/type-declarations
Open

feat: add typescript type declarations for analyzeCommits#961
Mearman wants to merge 1 commit into
semantic-release:masterfrom
Mearman:feat/type-declarations

Conversation

@Mearman

@Mearman Mearman commented Sep 8, 2026

Copy link
Copy Markdown

This package doesn't ship any TypeScript types right now — no .d.ts file, no types field in package.json — and there's no @types/semantic-release__commit-analyzer on npm either, so anyone calling analyzeCommits from TypeScript gets an implicit any for the whole module.

This adds an index.d.ts typing analyzeCommits(pluginConfig, context) and its return value. The shapes come straight from the JSDoc already on analyzeCommits in index.js and on the loader functions in lib/, plus the options table in the README (presetConfig in particular isn't in the JSDoc but is documented there). ReleaseType and AnalyzeCommitsContext are imported from semantic-release's own published types rather than redeclared, since anyone using this plugin already has semantic-release installed as a peer dependency.

I also had to change exports from the bare "./index.js" string to an object with a types condition — under moduleResolution: bundler/node16/nodenext, TypeScript only looks for a declaration file through a types condition inside exports once exports exists at all, it doesn't fall back to the top-level types field. I kept the top-level types field too for anyone still on classic resolution, and added index.d.ts to files so it's actually in the published tarball.

I checked this actually resolves correctly (not just "looks right") by packing the module with npm pack, installing the tarball into a scratch project, and compiling a small consumer file against it under bundler, node16, nodenext, and classic node/node10 resolution — all four pick up the types correctly, and @ts-expect-error on a couple of intentionally-wrong calls (missing pluginConfig, a ReleaseRule missing release) confirms it's real type-checking and not just resolving to any. npm test and publint --strict both pass unchanged.

This package has never shipped a .d.ts file or a "types" field in
package.json, and no @types/semantic-release__commit-analyzer exists
on npm, so a TypeScript consumer gets an implicit `any` for the whole
module.

Add index.d.ts declaring `analyzeCommits`, its `PluginConfig` and
`ReleaseRule` parameter shapes, and its `Promise<ReleaseType | null>`
return type. The shapes are drawn directly from the existing JSDoc in
index.js and lib/load-release-rules.js, and from the options table in
the README (which additionally documents `presetConfig`). `ReleaseType`
and `AnalyzeCommitsContext` are imported from semantic-release's own
published types rather than redeclared, since a consumer already has
semantic-release installed as this plugin's peer dependency.

Update "exports" to add a "types" condition, since moduleResolution
bundler/node16/nodenext only resolve declaration files through a
"types" condition inside "exports" and otherwise ignore a top-level
"types" field entirely. Keep the top-level "types" field too, for
classic Node resolution, and list index.d.ts in "files" so it is
actually included in the published package.
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.

1 participant