Loading…
Loading…
Five essential built-in generic utility types in TypeScript that will save you hundreds of lines of code.
Tags
Nine built-in TypeScript utility types that replace hundreds of lines of redundant interface definitions. Stop manually rewriting types -- use Partial, Omit, Pick, Record, ReturnType, Readonly, Extract, Exclude, and NonNullable.
You have a User type with ten properties. Now you need a type for update payloads (all optional), one for public profiles (no email/password), one for list views (just name and avatar). Without utility types, you write three nearly identical interfaces and keep them in sync manually.
Perfect for update/patch payloads where any subset of fields can be provided.
interface User {
id: string;
name: string;
email: string;
role: 'admin' | 'user';
}
// All properties become optional
type UpdateUserPayload = Partial<User>;
// { id?: string; name?: string; email?: string; role?: 'admin' | 'user' }
function updateUser(id: string, data: Partial<User>) {
// data can contain any combination of User fields
}Use when you want a few fields from a large type.
type UserPreview = Pick<User, 'id' | 'name'>;
// { id: string; name: string }Use when you want everything except a few fields.
type PublicUser = Omit<User, 'email' | 'role'>;
// { id: string; name: string }
type CreateUserPayload = Omit<User, 'id'>; // ID is auto-generated
// { name: string; email: string; role: 'admin' | 'user' }Creates an object type with specific key and value types. Great for dictionaries and lookup maps.
type UserRoles = 'admin' | 'editor' | 'viewer';
type RolePermissions = Record<UserRoles, string[]>;
// { admin: string[]; editor: string[]; viewer: string[] }
const permissions: RolePermissions = {
admin: ['read', 'write', 'delete'],
editor: ['read', 'write'],
viewer: ['read'],
};Useful when you want to type a variable based on what a function returns, without manually duplicating the type.
function getConfig() {
return { apiUrl: 'https://api.example.com', timeout: 5000, retries: 3 };
}
type AppConfig = ReturnType<typeof getConfig>;
// { apiUrl: string; timeout: number; retries: number }Makes all properties read-only at the type level. Useful for config objects and state that should not be mutated directly.
type ImmutableUser = Readonly<User>;
const user: ImmutableUser = { id: '1', name: 'Ada', email: 'ada@test.com', role: 'admin' };
// user.name = 'Bob'; // Error: Cannot assign to 'name' because it is a read-only propertyExtracts union members that are assignable to a given type.
type AllEvents = 'click' | 'scroll' | 'mouseover' | 'keydown' | 'keyup';
type MouseEvents = Extract<AllEvents, 'click' | 'mouseover' | 'scroll'>;
// 'click' | 'mouseover' | 'scroll'
// Practical: extract string-only types from a mixed union
type StringOrNumber = string | number | boolean;
type OnlyStrings = Extract<StringOrNumber, string>; // stringThe opposite of Extract -- removes specified members from a union.
type AllStatus = 'pending' | 'active' | 'suspended' | 'deleted';
type ActiveStatuses = Exclude<AllStatus, 'deleted' | 'suspended'>;
// 'pending' | 'active'Removes null and undefined from a type, useful when you have validated that a value exists.
type MaybeUser = User | null | undefined;
type DefiniteUser = NonNullable<MaybeUser>;
// User
function processUser(user: MaybeUser) {
if (!user) return;
const validUser: NonNullable<MaybeUser> = user; // Safe after null check
}These utility types are built into TypeScript -- no imports, no libraries. They compose together for powerful type transformations: Partial<Omit<User, 'id'>> gives you an optional-fields update payload without the ID. Readonly<Pick<User, 'id' | 'role'>> gives you an immutable subset. Instead of maintaining parallel type definitions that drift apart, you derive types from a single source of truth.
Utility types are built-in generic types in TypeScript that transform existing types into new ones, such as making all properties optional (Partial) or extracting specific keys (Pick), saving you from writing redundant type definitions.
Use Pick when you want to select a few properties from a large type, and use Omit when you want to exclude a few properties from a large type. Pick is better when selecting fewer fields than you are excluding.
Record<K, T> do in TypeScript?Record creates an object type where all keys are of type K and all values are of type T. For example, Record<string, number> defines an object with string keys and number values, useful for dictionaries and lookup maps.
Collaboration
I help startups and established companies design, build, and scale world-class digital products. From deep technical architecture to pixel-perfect UI: let's bring your vision to life.
Generate dynamic Open Graph images in Next.js using the ImageResponse API with custom fonts, gradients, and data-driven content for social sharing.
Create reusable GitHub Actions workflows with inputs, secrets, and outputs to eliminate YAML duplication across repositories and teams efficiently.
Process large files efficiently in Node.js using readable, writable, and transform streams to avoid memory issues and handle data chunk by chunk.