TypeScript stops being just JavaScript with types the moment you start writing types that do work. This post is a tour of the patterns I reach for most often when designing library APIs and shared internal utilities.
1. Conditional types as control flow
Conditional types let you branch on the shape of a generic. They behave like a tiny pure language inside the type system — and once you start treating them that way, the standard library's Pick, Omit, ReturnType all stop feeling like magic.
2. Mapped types for transformation
Mapped types iterate over the keys of a type. Combine them with as remapping and you can rename, filter, or fully restructure a type in a single declaration.
3. Template literal types for the API surface
If your library accepts strings shaped like "on:click" or "user.profile.name", you can encode the grammar in the type system instead of relying on runtime validation.
Closing
The point of all of this isn't cleverness — it's that a well-typed API teaches the next person how to use it without them ever opening the docs.