Utility Types: Partial, Pick, Omit, Record and More

intermediate
12 min

Utility Types: Partial, Pick, Omit, Record and More

TypeScript ships a standard library of utility types — generic type transformers that derive new types from existing ones. Instead of hand-writing near-duplicate interfaces (and letting them drift apart), you keep one source of truth and derive the variations. This lesson tours the utilities you will use constantly.

Throughout, we will transform this base type:

typescript
interface User { id: number; name: string; email: string; role: "admin" | "member"; }

Partial and Required

Partial<T> makes every property optional — perfect for update payloads:

typescript
function updateUser(id: number, changes: Partial<User>) { // merge changes into the stored user } updateUser(1, { name: "Ada King" }); // any subset of User is valid

Required<T> is the inverse: it strips ? from every property, guaranteeing a fully populated object.

Pick and Omit

Pick<T, K> keeps only the listed keys; Omit<T, K> removes them:

typescript
type UserPreview = Pick<User, "id" | "name">; // { id: number; name: string } type NewUser = Omit<User, "id">; // everything except id — ideal for a create form, // where the database assigns the id

Use Pick when the subset is small and stable; use Omit when you want "everything except". Because both derive from User, adding a field to User automatically flows into the derived types.

Record

Record<K, V> builds an object type with keys K and values V:

typescript
type Role = "admin" | "member" | "guest"; const permissions: Record<Role, string[]> = { admin: ["read", "write", "delete"], member: ["read", "write"], guest: ["read"], };

When the key type is a literal union, the compiler enforces completeness: forget the guest entry and you get an error. Record<string, T> is the loose dictionary form.

Readonly

Readonly<T> marks every property readonly — useful for configuration objects and immutable state:

typescript
const config: Readonly<{ apiUrl: string; retries: number }> = { apiUrl: "https://api.example.com", retries: 3, }; config.retries = 5; // Error

Note it is shallow: nested objects remain mutable unless they are also wrapped.

Function Utilities: ReturnType and Parameters

These extract types from functions, which is invaluable when a library does not export its internal types:

typescript
function createSession(userId: number, ttlSeconds: number) { return { userId, expiresAt: Date.now() + ttlSeconds * 1000 }; } type Session = ReturnType<typeof createSession>; // { userId: number; expiresAt: number } type CreateArgs = Parameters<typeof createSession>; // [userId: number, ttlSeconds: number] type Resolved = Awaited<Promise<string>>; // string

Union Utilities: Exclude, Extract, NonNullable

typescript
type Status = "active" | "banned" | "deleted"; type Visible = Exclude<Status, "deleted">; // "active" | "banned" type OnlyBanned = Extract<Status, "banned">; // "banned" type Definitely = NonNullable<string | null | undefined>; // string

Exclude filters members out of a union; Extract keeps only matching members; NonNullable drops null and undefined.

Composing Utilities

Utility types compose like functions. A common real-world example — an editable subset of a user:

typescript
type EditableUser = Partial<Omit<User, "id" | "role">>; // { name?: string; email?: string }

Under the hood these are all mapped types and conditional types, features you can use to build your own utilities once the built-ins run out.

Key Takeaways

  • Utility types derive variations from one source-of-truth type, so changes propagate automatically.
  • Partial/Required toggle optionality; Pick/Omit select keys; Record builds keyed objects with completeness checks.
  • ReturnType, Parameters, and Awaited extract types from functions and promises.
  • Exclude, Extract, and NonNullable filter unions.
  • Compose utilities freely — Partial<Omit<User, "id">> reads exactly like what it means.

Next lesson: Type Aliases vs Interfaces — when to use each way of naming a type.

Utility Types: Partial, Pick, Omit, Record and More - TypeScript | CodeYourCraft | CodeYourCraft