TypeScript Generics
ts-generics
Code Snippets
TypeScript Generic Utility Types Tour
TypeScript ships with a rich set of utility types (`Partial`, `Pick`, `Awaited`) and the language is expressive enough that you can build the rest yourself. This snippet tours the three most useful custom utilities (`DeepPartial`, `ValueOf`, and an `Awaited` recap), each with a runtime sentinel that proves the type lines up with the value. Use it as a one-page cheat sheet before reaching for individual deep dives in the rest of the catalog.
ValueOf Utility Type
`keyof` gives you the union of property names; `ValueOf<T>` gives you the union of property values. Combined with `as const` it derives a string-literal union from a single source-of-truth object, so the runtime constant and the static type can never drift. This snippet covers the one-line definition, an enum-replacement pattern, and a discriminator helper that drives type-safe `switch` blocks.
NonNullableKeys Utility Type
Filtering an object type to only the keys whose values are not nullable comes up everywhere: required-fields lists, mandatory column sets, GraphQL non-null fields. This snippet builds a `NonNullableKeys<T>` that returns just those keys, then layers in a `RequiredFields<T>` that produces a sub-object type, and a runtime helper that strips nullable fields from a value at runtime.
RequireAtLeastOne Utility Type
API endpoints often want 'pass at least one of these search params, but not necessarily all of them' (`{ id }`, `{ email }`, `{ id, email }`, but never `{}`). TypeScript's stock utilities cannot express that constraint, but a small `RequireAtLeastOne<T>` does. This snippet builds the type, layers in a `RequireExactlyOne` variant for either-or constraints, and shows a runtime guard that pairs with both.
Branded (Nominal) Types
TypeScript is structurally typed, so `type UserId = string` and `type OrderId = string` are interchangeable to the compiler, which is exactly the bug class you want to prevent. Branded (nominal) types attach a phantom tag so the two stay distinct at compile time without any runtime cost. This snippet covers the basic brand pattern, a parser-style smart constructor that produces a brand from a raw value, and a multi-brand domain model that ties them together.
UnionToIntersection Utility Type
Going from a union (`A | B | C`) to an intersection (`A & B & C`) is what you need when you want to merge handler shapes, deduce the most-specific type, or express a 'must satisfy all branches' constraint. TypeScript has no built-in for this, but a single conditional with `infer` does the job. This snippet builds the type, walks through how distributive conditionals make it work, and ties it to a concrete LastInUnion / merged-handlers example.
Infer a Type from a Zod Schema
Maintaining a Zod runtime schema and a TypeScript interface that match by hand is a maintenance trap: every field change has to be edited twice. `z.infer<typeof Schema>` derives the static type from the schema, so the schema is the single source of truth. This snippet covers the basic infer pattern, the input/output split for transforms, and a typed parsing wrapper that turns runtime errors into a clean `Result` shape.
Fixed-Length Tuple via Generics
Constraining an argument to 'an array of exactly 4 numbers' is a common need (RGBA, 4x4 matrices, fixed-length feature vectors). TypeScript can express it with a recursive `TupleOf<T, N>` that builds up `[T, T, T, ...]` of the requested length. This snippet covers the recursive construction, a runtime helper that produces a value matching the type, and a length-comparison variant useful for richer constraints ("at least N", "between N and M").
