TypeScript Utility Types: The Built-in Ones You Need, With Examples

TypeScript utility types are generic types that ship with the language and transform one type into another. Partial<User> makes every property optional, Pick<User, 'id'> keeps only some, and Omit<User, 'password'> removes some. They save you from rewriting near-duplicate interfaces, and they are the fastest way to keep types in sync with a single source of truth. Here are the ones I use constantly, with examples, and a few custom helpers that fill the gaps.

I originally wrote this in 2023 and have updated it to cover newer additions like NoInfer.

TypeScript Utility Types at a Glance

Utility typeWhat it does
Partial<T>Makes all properties optional
Required<T>Makes all properties required
Readonly<T>Makes all properties read-only
Pick<T, K>Keeps only the listed keys
Omit<T, K>Removes the listed keys
Record<K, V>Object type with keys K and values V
Exclude<U, X>Removes members from a union
Extract<U, X>Keeps members of a union
NonNullable<T>Removes null and undefined
ReturnType<F>The return type of a function
Parameters<F>The parameter types of a function as a tuple
Awaited<T>The resolved type of a Promise
NoInfer<T>Blocks type inference from a position (TypeScript 5.4+)

Partial<Type>

Partial creates a new type where every property is optional. Use it for update payloads and optional configuration objects, something you see everywhere in typed ORM layers like Drizzle and Prisma.

typescript
interface User {
  id: number;
  name: string;
  email: string;
}

type PartialUser = Partial<User>;
// { id?: number; name?: string; email?: string }

Required<Type> is the inverse: it removes the ? from every property.

Readonly<Type>

Readonly marks every property as read-only, so assignments to them are compile errors. It is handy for configuration and state you never want to mutate.

typescript
interface Config {
  url: string;
  apiKey: string;
}

type ReadonlyConfig = Readonly<Config>;

Pick<Type, Keys>

Pick builds a new type by selecting specific properties. Use it to expose only a subset of a large object.

typescript
interface User {
  id: number;
  name: string;
  email: string;
  password: string;
}

type PublicUser = Pick<User, 'id' | 'name' | 'email'>;

Omit<Type, Keys>

Omit is the opposite of Pick: it excludes properties. It is the one I reach for to strip sensitive fields.

typescript
type UserWithoutPassword = Omit<User, 'password'>;

Record<Keys, Type>

Record creates an object type with a given set of keys and a single value type. It is a clean way to type dictionaries and lookup tables.

typescript
type Role = 'admin' | 'editor' | 'viewer';

const permissions: Record<Role, string[]> = {
  admin: ['read', 'write', 'delete'],
  editor: ['read', 'write'],
  viewer: ['read'],
};

Because the keys are a union, TypeScript errors if you forget a role.

Exclude, Extract and NonNullable

These three work on unions.

typescript
type Status = 'idle' | 'loading' | 'error' | 'done';

type Active = Exclude<Status, 'idle'>; // 'loading' | 'error' | 'done'
type Failed = Extract<Status, 'error' | 'timeout'>; // 'error'
type Name = NonNullable<string | null | undefined>; // string

ReturnType and Parameters

ReturnType extracts what a function returns. Parameters extracts its arguments as a tuple. Both are useful when you want to type something from a function you do not control.

typescript
function getUser(id: number): { id: number; name: string } {
  return { id, name: 'Alex' };
}

type UserResult = ReturnType<typeof getUser>;
type GetUserArgs = Parameters<typeof getUser>; // [id: number]

Awaited<Type>

Awaited unwraps a Promise, including nested ones. Combine it with ReturnType to get the resolved value of an async function:

typescript
async function fetchUser(): Promise<User> {
  // ...
  return {} as User;
}

type FetchedUser = Awaited<ReturnType<typeof fetchUser>>; // User

Note that ReturnType<typeof fetchUser> alone is Promise<User>, not User. That is the mistake Awaited fixes.

NoInfer<Type>

NoInfer (TypeScript 5.4) stops a parameter from being used to infer a generic. Without it, a default value can widen the type:

typescript
function createStore<T extends string>(values: T[], initial: NoInfer<T>) {
  return { values, current: initial };
}

createStore(['a', 'b'], 'c'); // error: 'c' is not 'a' | 'b'

Without NoInfer, TypeScript would infer T as 'a' | 'b' | 'c' and accept the call.

Custom Utility Types Worth Writing

The built-ins do not cover everything. Two helpers I add to most projects:

typescript
// Makes every property optional, recursively
type DeepPartial<T> = {
  [K in keyof T]?: T[K] extends object ? DeepPartial<T[K]> : T[K];
};

// Flattens intersections so hover tooltips show a readable type
type Prettify<T> = {
  [K in keyof T]: T[K];
} & {};

DeepPartial is useful for nested config overrides. Prettify has no runtime effect. It just makes editor tooltips show one flat object instead of A & B & C.

A Performance Warning

Deeply recursive utility types like DeepPartial or DeepReadonly that walk an unbounded tree are where much of the large-codebase compile-time pain comes from. Use them on small, well-bounded shapes, and read the TypeScript performance guide before they sneak into hot paths. Utility types are erased at runtime, so they cost nothing when the program runs, but they do cost compiler time. If compile time is the bottleneck, TypeScript 7's Go compiler helps too.

Frequently Asked

What are TypeScript utility types? Built-in generic types such as Partial, Pick, Omit and Record that transform existing types, so you do not have to write variants by hand.

What is the difference between Pick and Omit? Pick keeps the keys you list. Omit removes them. Use whichever list is shorter.

What is the difference between Partial and Required? Partial makes every property optional. Required makes every property mandatory.

How do I get the resolved type of an async function? Use Awaited<ReturnType<typeof fn>>.

Do utility types affect runtime performance? No. Types are erased at compile time, though complex recursive types can slow down the compiler.