BeCuriouzLearn something new every day
Utility Types: Transform Types Without Retyping Them
💡 Utility types derive new types from a single source of truth, so your types transform automatically instead of drifting out of sync.
You've built a User type. Now you need a version where every field is optional (for a patch update), another where you only want two fields, and a lookup table keyed by user ID. Retyping all of these by hand would be repetitive and would drift out of sync the moment User changes. Utility types are built-in generic types that derive new types from existing ones, so a single source of truth stays authoritative.
The most common ones map cleanly to plain-English verbs. Partial makes every property optional; Required does the reverse. Pick keeps only the listed keys; Omit drops them. Record builds an object type with keys K and values V.
interface User { id: number; name: string; email: string }
type Patch = Partial<User>; // all fields optional
type Preview = Pick<User, 'id' | 'name'>; // { id; name }
type NoId = Omit<User, 'id'>; // { name; email }
type ById = Record<number, User>; // { [k: number]: User }Others extract types from values, not other types. ReturnType grabs what a function returns and Parameters grabs its argument tuple — both usually paired with typeof so you never hand-copy a signature. Because these are just generics (recall how keyof and mapped types work from earlier cards), they compose: Partial is perfectly valid.
function makeUser() { return { id: 1, name: 'Ada' }; }
type Made = ReturnType<typeof makeUser>; // { id: number; name: string }