feat: ship TypeScript declarations - #33
Merged
Merged
Conversation
No types meant every TypeScript consumer got an implicit `any` and had to either write their own declarations or reach for a different library. That is the first thing an evaluator checks, and npm shows it on the listing. The declarations are hand-written rather than generated: the source is plain JS with JSDoc, and generating from it produced a weaker surface than writing the ~140 lines directly. Two things the types encode that the docs previously only implied: coordinates are always in the image's original pixels, and the style objects replace the defaults wholesale instead of merging into them, so a partial override silently unsets everything it omits. Added `npm run types:check` (tsc --noEmit) over a compile-time test that exercises the full surface, including negative cases, and wired it into CI — declarations that drift from the implementation are worse than none. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This was referenced Sep 6, 2026
The declarations documented the shallow-merge behaviour these comments were written against. #36 fixes that merge, so the note that a partial override unsets everything it omits no longer holds. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…rations # Conflicts: # CHANGELOG.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
P1, item 1 of the discoverability plan.
Why
No types meant every TypeScript consumer got an implicit
anyand had to write their own declarations or pick a different library. It is the first thing an evaluator checks, and npm surfaces it on the package listing.What changed
src/index.d.ts— hand-written, ~140 lines. Generating from the JSDoc produced a weaker surface than writing it directly, since the source is plain JS.package.json—typesentry point plus atypescondition first in theexportsmap, so bothbundlerandnode16/nodenextresolution find it.npm run types:check—tsc --noEmitovertypes-test.ts, a compile-time exercise of the whole public surface including@ts-expect-errornegative cases. Wired into the Code Quality workflow. Declarations that silently drift from the implementation are worse than no declarations.Two things the types make explicit
The docs previously only implied both:
style/handleStyleobjects replace the defaults rather than merging into them — a partial override silently unsets every property it omits. Documented in the declarations; worth fixing in the implementation separately.Verification
Beyond CI, I packed the tarball and installed it into a scratch project under
moduleResolution: NodeNext. Types resolve, andgetFocusPoint().xcorrectly types asnumber.npm test(13 passing),lint:check,format:checkandtypes:checkall green. The declarations ship (3.8 kB);types-test.tsandtsconfig.jsondo not.🤖 Generated with Claude Code