Tools
Tools: TypeScript Utility Types: A Complete Guide
2026-02-17
0 views
admin
Why Utility Types Matter ## Partial<T> ## Required<T> ## Pick<T, K> ## Omit<T, K> ## Record<K, T> ## Practical Example: API Response Types ## Key Takeaways TypeScript's built-in utility types are powerful tools that help you write cleaner, more maintainable code. In this guide, I'll walk through the most commonly used utility types with practical examples from real-world applications. When building large-scale applications like the ones I work on at Expedia Group, type safety isn't just nice to have — it's essential. Utility types help you derive new types from existing ones without duplication. Makes all properties of T optional. This is incredibly useful for update functions. The opposite of Partial — makes all properties required. Creates a type with only the specified properties. Creates a type excluding the specified properties. Creates a type with keys of type K and values of type T. Here's how I combine these utility types in real projects: Mastering these utility types will significantly improve your TypeScript code quality and developer experience. Originally published at umesh-malik.com Templates let you quickly answer FAQs or store snippets for re-use. Are you sure you want to hide this comment? It will become hidden in your post, but will still be visible via the comment's permalink. Hide child comments as well For further actions, you may consider blocking this person and/or reporting abuse CODE_BLOCK:
interface User { id: string; name: string; email: string; role: 'admin' | 'user';
} function updateUser(id: string, updates: Partial<User>) { // Only update the fields that were provided
} updateUser('123', { name: 'Umesh' }); // Valid! Enter fullscreen mode Exit fullscreen mode CODE_BLOCK:
interface User { id: string; name: string; email: string; role: 'admin' | 'user';
} function updateUser(id: string, updates: Partial<User>) { // Only update the fields that were provided
} updateUser('123', { name: 'Umesh' }); // Valid! CODE_BLOCK:
interface User { id: string; name: string; email: string; role: 'admin' | 'user';
} function updateUser(id: string, updates: Partial<User>) { // Only update the fields that were provided
} updateUser('123', { name: 'Umesh' }); // Valid! COMMAND_BLOCK:
interface Config { host?: string; port?: number; debug?: boolean;
} const defaultConfig: Required<Config> = { host: 'localhost', port: 3000, debug: false,
}; Enter fullscreen mode Exit fullscreen mode COMMAND_BLOCK:
interface Config { host?: string; port?: number; debug?: boolean;
} const defaultConfig: Required<Config> = { host: 'localhost', port: 3000, debug: false,
}; COMMAND_BLOCK:
interface Config { host?: string; port?: number; debug?: boolean;
} const defaultConfig: Required<Config> = { host: 'localhost', port: 3000, debug: false,
}; CODE_BLOCK:
type UserPreview = Pick<User, 'id' | 'name'>; // Equivalent to:
// { id: string; name: string } Enter fullscreen mode Exit fullscreen mode CODE_BLOCK:
type UserPreview = Pick<User, 'id' | 'name'>; // Equivalent to:
// { id: string; name: string } CODE_BLOCK:
type UserPreview = Pick<User, 'id' | 'name'>; // Equivalent to:
// { id: string; name: string } CODE_BLOCK:
type CreateUserInput = Omit<User, 'id'>; // Everything except id Enter fullscreen mode Exit fullscreen mode CODE_BLOCK:
type CreateUserInput = Omit<User, 'id'>; // Everything except id CODE_BLOCK:
type CreateUserInput = Omit<User, 'id'>; // Everything except id CODE_BLOCK:
type UserRoles = Record<string, User[]>; const roleMap: UserRoles = { admin: [/* admin users */], editor: [/* editor users */],
}; Enter fullscreen mode Exit fullscreen mode CODE_BLOCK:
type UserRoles = Record<string, User[]>; const roleMap: UserRoles = { admin: [/* admin users */], editor: [/* editor users */],
}; CODE_BLOCK:
type UserRoles = Record<string, User[]>; const roleMap: UserRoles = { admin: [/* admin users */], editor: [/* editor users */],
}; COMMAND_BLOCK:
interface ApiResponse<T> { data: T; status: number; message: string;
} type UserListResponse = ApiResponse<Pick<User, 'id' | 'name' | 'role'>[]>;
type UserUpdatePayload = Partial<Omit<User, 'id'>>; Enter fullscreen mode Exit fullscreen mode COMMAND_BLOCK:
interface ApiResponse<T> { data: T; status: number; message: string;
} type UserListResponse = ApiResponse<Pick<User, 'id' | 'name' | 'role'>[]>;
type UserUpdatePayload = Partial<Omit<User, 'id'>>; COMMAND_BLOCK:
interface ApiResponse<T> { data: T; status: number; message: string;
} type UserListResponse = ApiResponse<Pick<User, 'id' | 'name' | 'role'>[]>;
type UserUpdatePayload = Partial<Omit<User, 'id'>>; - Use Partial for update operations where not all fields are required
- Use Pick and Omit to create focused types from larger interfaces
- Use Record for dictionary-like structures
- Combine utility types for complex transformations
- These types are zero-cost at runtime — they only exist during compilation
how-totutorialguidedev.toai