Type-safe clients and testing
Test the contract, not the types
Add runtime negative tests, compatibility examples, and response assertions around the inferred client.
9 minute lesson
The suite verifies error shapes, status codes, headers, pagination boundaries, and unknown fields using raw requests. This is a small part of a typed bookmarks API built with Hono, tested in memory, and deployed once to Node and once to Cloudflare Workers, but the boundary it creates affects everything that follows.
Types catch many development mistakes, but deployed clients can be old, untyped, compromised, or simply wrong. The useful target is not encyclopedic coverage. Make one deliberate choice, observe its consequences, and know which requirement would make you revise it.
Watch for one shortcut in particular: trying to delete runtime validation because the trusted TypeScript client compiles. It makes later failures harder to locate. Instead, treat types as developer feedback and HTTP tests as evidence about the deployed boundary. Prefer an implementation you can explain from the outside before optimizing it.
Keep the wider goal in view: Test the real Hono app and use inferred clients without pretending compile-time types validate network data at runtime. A short observation with concrete evidence is more useful than a confident sentence with no reproduction path.
Write one test that cannot be expressed as a valid typed client call and verify the server’s defensive response. Hand the result to someone else and see whether the behavior is clear without an oral explanation.
Lesson completed