BeCuriouzBeCuriouz

Learn something new every day

🔷 TypeScript
🧰

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.

ts
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.

ts
function makeUser() { return { id: 1, name: 'Ada' }; }
type Made = ReturnType<typeof makeUser>;  // { id: number; name: string }
🧰 Utility Types: Transform Types Without Retyping Them — BeCuriouz