If you’ve been using TypeScript for a while, you’ve probably written repetitive types — like copying an interface just to make all fields optional or removing one key from another type.
That’s where TypeScript Utility Types come in. They’re built-in helpers that let you transform existing types instead of creating new ones from scratch.
In this post, we’ll explore the most useful ones — with real examples you can instantly apply in your React, NextJS, Node.js, or MERN projects.
🔧 1. Partial<Type> — Make All Properties Optional
The
Partialutility type turns all properties of a given type into optional.
javascriptinterface User { id: number; name: string; email: string; } type UpdateUser = Partial<User>; const updateUser: UpdateUser = { name: "John", };
🟢 When to use:
When you’re creating “update” forms or API payloads that don’t require all fields.
✂️ 2. Pick<Type, Keys> — Select Specific Properties
Pick lets you choose only certain properties from a type.
javascriptinterface User { id: number; name: string; email: string; password: string; } type PublicUser = Pick<User, "id" | "name">; const user: PublicUser = { id: 1, name: "John", };
🟢 When to use:
When you need to expose only public data (e.g., remove sensitive info like passwords).
🚫 3. Omit<Type, Keys> — Exclude Certain Properties
The opposite of Pick. It creates a type by omitting specific properties.
javascripttype SafeUser = Omit<User, "password">; const safeUser: SafeUser = { id: 1, name: "john", email: "john@example.com", };
🟢 When to use:
When you want to reuse an existing type but hide specific fields.
🔒 4. Readonly<Type> — Prevent Modification
Marks all properties of a type as read-only.
javascriptinterface Config { apiUrl: string; version: number; } const config: Readonly<Config> = { apiUrl: "https://api.example.com", version: 1, }; // ❌ Error: Cannot assign to 'apiUrl' because it is a read-only property. config.apiUrl = "https://new-api.example.com";
🟢 When to use:
For constant configurations or environment settings.
🗂️ 5. Record<Keys, Type> — Create an Object Type Dynamically
The Record utility constructs an object type with a set of keys and a uniform type.
javascripttype Roles = "admin" | "user" | "guest"; const permissions: Record<Roles, boolean> = { admin: true, user: true, guest: false, };
🟢 When to use:
When you need to map a fixed set of keys (like roles, statuses, or categories) to values.
🧩 6. Required<Type> — Make All Properties Mandatory
Turns all properties of a type into required.
javascriptinterface Settings { theme?: string; language?: string; } type StrictSettings = Required<Settings>; const settings: StrictSettings = { theme: "dark", language: "en", };
🟢 When to use:
When you want to enforce that all fields must exist, even if they were optional before.
🧰 Bonus: Combine Utility Types
You can mix them for more powerful transformations.
javascripttype UserPreview = Readonly<Pick<User, "id" | "name">>; const userPreview: UserPreview = { id: 1, name: "John", }; // userPreview.id = 2 ❌ Error (readonly)
🟢 When to use:
When you want fine-grained control over types — like a read-only subset of user data.
Utility types are small but powerful tools that make TypeScript a joy to work with.
Once you start using them, you’ll rarely find yourself rewriting similar interfaces again.
Here’s a quick recap:
| Utility Type | Purpose | 
|---|---|
| Partial<T> | Make all properties optional | 
| Pick<T, K> | Select specific keys | 
| Omit<T, K> | Exclude specific keys | 
| Readonly<T> | Make all properties immutable | 
| Record<K, T> | Create a type with specific keys and value types | 
| Required<T> | Make all properties required | 
If you enjoyed this guide, you can find more tutorials on my portfolio blog 🚀

