Type safety is cheapest at the boundary. Validate once, at the edge, then trust the types all the way down.
Derive, don’t duplicate
Define your contract in one place and let the types flow from it.
interface CreateUser {
email: string
name: string
role: 'admin' | 'member'
}
function createUser(input: CreateUser) {
// input is already typed and validated here
}
<h2 id="push-unknowns-to-the-perimeter">Push unknowns to the perimeter</h2>
<p>:::tip
The moment data crosses a network boundary, treat it as <code>unknown</code>. Validate it into a known shape before it touches business logic.
:::</p>
<h2 id="benefits-you-feel-immediately">Benefits you feel immediately</h2>
<ol>
<li>Refactors become mechanical instead of detective work</li>
<li>Endpoint contracts are documented by the compiler</li>
<li>A large family of runtime errors simply cannot compile</li>
</ol>
<blockquote>
<p>Types are a conversation with your future self. Make it a kind one.</p>
</blockquote>
Comments
Comments are disabled for now. We're preparing a first-class experience powered by Giscus, Disqus or GitHub Discussions.