BytePane

TypeScript Utility Types Handbook 2026: Omit, Pick, Partial + All 22 Built-ins

TypeScriptUpdated May 26, 202617 min read

Quick answer

TypeScript utility types are built-in generic helpers that transform existing types into safer API contracts, form states, component props, and function wrappers. Checked against the official TypeScript handbook on May 26, 2026, the set below covers 18 named utilities plus four intrinsic string helpers: Omit, Pick, Partial, Record, Awaited, NoInfer, function helpers, this helpers, and string-literal helpers.

Reviewed May 26, 2026

Source review: TypeScript handbook utility types

This refresh follows the official TypeScript utility-types reference, mapped-types guide, conditional-types guide, template-literal-types guide, and release notes for Omit, Awaited, and NoInfer. It is intended as a practical handbook layer, not a replacement for compiler documentation.

Practical checks

  • 1.Use Omit or Pick for object properties; use Exclude or Extract for union members.
  • 2.Treat Readonly as shallow unless the project defines and reviews a DeepReadonly helper.
  • 3.Use Awaited with ReturnType for async functions instead of copying resolved response types.
  • 4.Use NoInfer only when one argument should define the generic source of truth.

Related BytePane tools

What Are Utility Types?

TypeScript provides a set of built-in generic types that transform existing types into new ones. These utility types eliminate the need to manually redefine types for common patterns like making properties optional, picking a subset of fields, or creating dictionary types. Instead of duplicating type definitions across your codebase, you derive new types from a single source of truth.

This guide covers every commonly used utility type with real-world examples from API development, React components, and data processing. By the end, you will also know how to build your own custom utility types.

Which Utility Type Should You Use?

TaskUseAvoid
Create a PATCH or form draft typePartial<T>Duplicating a second UpdateUser interface by hand
Return only public fields from a modelOmit<T, "password" | "token">Forgetting one sensitive field in a copied type
Send only a small API response shapePick<T, "id" | "name">Omit when the exclude list is longer than the keep list
Model known dictionary keysRecord<Status, Handler>Open index signatures when the key set is finite
Filter a discriminated unionExtract<T, Match> or Exclude<T, Match>Using Omit, which removes object keys rather than union members
Reuse an async function result typeAwaited<ReturnType<typeof fn>>Manually copying a Promise result shape
Keep a generic default from wideningNoInfer<T>Letting a second argument redefine the generic source of truth

All 22 Built-in Utility Types at a Glance

Utility TypeGroupWhat It DoesCommon Use Case
Partial<T>Object shapeMake every property optionalPATCH payloads, form draft state
Required<T>Object shapeMake every property requiredConfig after defaults are merged
Readonly<T>Object shapeMake properties read-onlyImmutable state, frozen API models
Record<K, V>Object shapeCreate typed dictionariesLookup tables and grouped rows
Pick<T, K>Object shapeKeep only selected keysPublic DTOs and component props
Omit<T, K>Object shapeRemove selected keysHide passwords and server-only fields
Exclude<T, U>Union filtersRemove union membersRemove deleted or unsupported states
Extract<T, U>Union filtersKeep matching union membersSelect one event kind from a union
NonNullable<T>Union filtersRemove null and undefinedPost-validation value types
Parameters<T>Function helpersGet a function parameter tupleTyped wrappers and instrumentation
ConstructorParameters<T>Function helpersGet constructor parameter tupleFactories around classes
ReturnType<T>Function helpersGet function return typeInfer service or selector outputs
InstanceType<T>Function helpersGet class instance typeDI containers and factory output
NoInfer<T>Inference controlBlock inference from one argumentKeep a generic source of truth stable
ThisParameterType<T>This helpersExtract a function this parameterLegacy APIs and method binding
OmitThisParameter<T>This helpersRemove a function this parameterBind methods into callbacks
ThisType<T>This helpersContextual this marker for objectsObject-literal DSLs
Awaited<T>Promise helpersUnwrap Promise-like resultsAsync return values from services
Uppercase<S>String helpersUppercase a string literal typeGenerated constant keys
Lowercase<S>String helpersLowercase a string literal typeNormalize route/event names
Capitalize<S>String helpersCapitalize first characterGetter/setter type names
Uncapitalize<S>String helpersUncapitalize first characterConvert display keys to object keys

TypeScript Utility Types by Release Version

The practical takeaway: older projects usually have Partial, Pick, and Record, but Omit, Awaited, and NoInfer depend on newer compiler baselines.

ReleaseUtility typesWhy it matters
TS 2.1Partial, Readonly, Record, PickThe first everyday object-shape helpers for optional fields, immutable fields, dictionaries, and selected keys.
TS 2.3ThisTypeContextual this typing for object-literal APIs and DSLs.
TS 2.8Required, Exclude, Extract, NonNullable, ReturnType, InstanceTypeConditional-type era helpers for required fields, union filtering, null cleanup, and function/class inference.
TS 3.1Parameters, ConstructorParametersTuple extraction helpers for wrapping functions and constructors without duplicating signatures.
TS 3.3ThisParameterType, OmitThisParameterHelpers for binding or adapting legacy functions that declare an explicit this parameter.
TS 3.5OmitThe opposite of Pick: keep most properties while dropping a few object keys.
TS 4.1Uppercase, Lowercase, Capitalize, UncapitalizeString-literal helpers for template literal types, generated keys, routes, and event names.
TS 4.5AwaitedPromise-like unwrapping for async APIs and ReturnType composition.
TS 5.4NoInferInference control when one argument should define a generic and another should only be checked against it.

Source note: the official utility-types page lists release markers for the named helpers and links the intrinsic string helpers to template literal types; the release notes confirm Omit in TypeScript 3.5, Awaited in TypeScript 4.5, and NoInfer in TypeScript 5.4.

Partial<T>: Make Everything Optional

Partial<T> creates a type where every property of T becomes optional. This is the most commonly used utility type, especially for update operations where only some fields change.

interface User {
  id: string;
  name: string;
  email: string;
  avatar: string;
  role: 'admin' | 'user';
}

// Without Partial -- you'd need a separate type:
// interface UpdateUser { name?: string; email?: string; ... }

// With Partial -- derive it automatically:
type UpdateUser = Partial<User>;
// { id?: string; name?: string; email?: string; avatar?: string; role?: 'admin' | 'user' }

// Real-world usage: update function
async function updateUser(id: string, data: Partial<User>): Promise<User> {
  // Only the provided fields are updated
  return await db.users.update({ where: { id }, data });
}

// Usage -- only update what changed
await updateUser('user_123', { name: 'New Name' });        // OK
await updateUser('user_123', { email: '[email protected]' }); // OK
await updateUser('user_123', {});                            // OK (no changes)

// React form state
const [formData, setFormData] = useState<Partial<User>>({});

function handleChange(field: keyof User, value: string) {
  setFormData(prev => ({ ...prev, [field]: value }));
}

Pick<T, K> and Omit<T, K>: Select or Exclude Properties

Pick selects specific properties; Omit removes specific properties. They are complementary tools for creating focused type subsets from larger interfaces.

interface User {
  id: string;
  name: string;
  email: string;
  password: string;
  createdAt: Date;
  updatedAt: Date;
}

// Pick: select only what you need
type UserPreview = Pick<User, 'id' | 'name' | 'avatar'>;
// { id: string; name: string; avatar: string }

// Omit: remove what you don't want
type PublicUser = Omit<User, 'password'>;
// { id: string; name: string; email: string; createdAt: Date; updatedAt: Date }

// API layer: never expose password
function getUserProfile(id: string): Promise<PublicUser> {
  const user = await db.users.findById(id);
  const { password, ...publicUser } = user; // strip password
  return publicUser;
}

// Create form: no id or timestamps (server generates those)
type CreateUserInput = Omit<User, 'id' | 'createdAt' | 'updatedAt'>;
// { name: string; email: string; password: string }

// Combine with Partial for flexible update
type UpdateUserInput = Partial<Omit<User, 'id' | 'createdAt'>>;
// { name?: string; email?: string; password?: string; updatedAt?: Date }

// React component props
type UserCardProps = Pick<User, 'name' | 'email'> & {
  onClick: () => void;
};

Record<K, V>: Dictionary Types

Record<K, V> creates a type with keys of type K and values of type V. It is the type-safe way to define dictionaries, lookup tables, and grouped data.

// Simple dictionary
type UserMap = Record<string, User>;
const users: UserMap = {
  'user_1': { id: 'user_1', name: 'Alice', ... },
  'user_2': { id: 'user_2', name: 'Bob', ... },
};

// Constrained keys with union type
type Theme = 'light' | 'dark' | 'auto';
type ThemeConfig = Record<Theme, { bg: string; text: string; border: string }>;

const themes: ThemeConfig = {
  light: { bg: '#ffffff', text: '#1a1a1a', border: '#e5e5e5' },
  dark:  { bg: '#0a0a0a', text: '#fafafa', border: '#333333' },
  auto:  { bg: 'inherit', text: 'inherit', border: 'inherit' },
};

// HTTP status code descriptions
type StatusCode = 200 | 201 | 400 | 401 | 403 | 404 | 500;
const statusMessages: Record<StatusCode, string> = {
  200: 'OK',
  201: 'Created',
  400: 'Bad Request',
  401: 'Unauthorized',
  403: 'Forbidden',
  404: 'Not Found',
  500: 'Internal Server Error',
};

// Grouped data
type GroupedByRole = Record<User['role'], User[]>;
const grouped: GroupedByRole = {
  admin: [adminUser1, adminUser2],
  user: [user1, user2, user3],
};

Record types are especially useful when working with JSON data. Format and inspect JSON objects with our JSON Formatter to understand the data shape before defining your Record types.

Exclude<T, U> and Extract<T, U>: Filter Union Types

type Status = 'pending' | 'active' | 'suspended' | 'deleted';

// Exclude: remove members from a union
type ActiveStatus = Exclude<Status, 'deleted' | 'suspended'>;
// 'pending' | 'active'

// Extract: keep only members matching a condition
type InactiveStatus = Extract<Status, 'suspended' | 'deleted'>;
// 'suspended' | 'deleted'

// Real-world: event system
type AppEvent =
  | { type: 'click'; x: number; y: number }
  | { type: 'keydown'; key: string }
  | { type: 'scroll'; offset: number }
  | { type: 'resize'; width: number; height: number };

// Extract only mouse-related events
type MouseEvent = Extract<AppEvent, { type: 'click' }>;
// { type: 'click'; x: number; y: number }

// Exclude specific events from handling
type NonScrollEvent = Exclude<AppEvent, { type: 'scroll' }>;

// Extract event types as a union of strings
type EventType = AppEvent['type'];
// 'click' | 'keydown' | 'scroll' | 'resize'

ReturnType<T> and Parameters<T>: Infer from Functions

// ReturnType: extract a function's return type
function createUser(name: string, email: string) {
  return { id: crypto.randomUUID(), name, email, createdAt: new Date() };
}

type NewUser = ReturnType<typeof createUser>;
// { id: string; name: string; email: string; createdAt: Date }

// Parameters: extract function parameter types as a tuple
type CreateUserParams = Parameters<typeof createUser>;
// [name: string, email: string]

// Real-world: wrapping third-party functions
import { fetchData } from 'some-library';

type FetchResult = ReturnType<typeof fetchData>;
type FetchArgs = Parameters<typeof fetchData>;

// Create a wrapper with the same signature
function cachedFetch(...args: FetchArgs): FetchResult {
  const cacheKey = JSON.stringify(args);
  if (cache.has(cacheKey)) return cache.get(cacheKey);
  const result = fetchData(...args);
  cache.set(cacheKey, result);
  return result;
}

// Awaited: unwrap Promise return types
async function getUser(id: string): Promise<User> { ... }

type UserResult = Awaited<ReturnType<typeof getUser>>;
// User (not Promise<User>)

Building Custom Utility Types

Once you understand the built-in utilities, you can build your own using mapped types, conditional types, and template literal types. Here are practical custom utilities used in production codebases.

// DeepPartial: recursively make all properties optional
type DeepPartial<T> = {
  [P in keyof T]?: T[P] extends object ? DeepPartial<T[P]> : T[P];
};

interface Config {
  server: { host: string; port: number };
  database: { url: string; pool: { min: number; max: number } };
}

// All nested properties are optional
type PartialConfig = DeepPartial<Config>;

// Nullable: make a type nullable
type Nullable<T> = T | null;

// PickByType: pick properties that match a specific value type
type PickByType<T, ValueType> = {
  [K in keyof T as T[K] extends ValueType ? K : never]: T[K];
};

type StringFields = PickByType<User, string>;
// { id: string; name: string; email: string }

// RequireAtLeastOne: at least one property must be provided
type RequireAtLeastOne<T> = {
  [K in keyof T]-?: Required<Pick<T, K>> & Partial<Omit<T, K>>;
}[keyof T];

type SearchParams = RequireAtLeastOne<{
  name: string;
  email: string;
  id: string;
}>;
// Must provide at least name, email, or id

// StrictOmit: Omit that errors on non-existent keys
type StrictOmit<T, K extends keyof T> = Omit<T, K>;
// StrictOmit<User, 'nonExistent'> -> compile error!
// Omit<User, 'nonExistent'> -> silently returns User

Best Practices

  1. Derive, do not duplicate -- use utility types to create variants from a single source type instead of maintaining parallel interfaces that drift apart.
  2. Name derived types clearly -- CreateUserInput is better than UserPartialOmitId. The name should describe usage, not implementation.
  3. Use Pick for API boundaries -- define exactly which fields an API endpoint accepts or returns. This documents the contract and catches breaking changes.
  4. Combine utilities -- Partial<Omit<User, 'id'>> is perfectly valid and reads clearly: "optional fields except id."
  5. Prefer Record over index signatures -- Record<string, User> is more explicit than { [key: string]: User } and works better with constrained key types.
  6. Do not over-abstract -- complex nested utility types become unreadable. If a type is hard to understand, define it explicitly with an interface.

Frequently Asked Questions

How many TypeScript utility types are in the handbook in 2026?
The handbook lists 18 named utility helpers plus four intrinsic string manipulation helpers: Uppercase, Lowercase, Capitalize, and Uncapitalize. This guide treats those as 22 commonly referenced built-ins and groups them by the job they solve.
What is the difference between Pick and Omit in TypeScript?
Pick<T, K> creates a new type by selecting specific properties from T. Omit<T, K> creates a new type by excluding specific properties from T. They are complementary: Pick is best when you need a few properties from a large type, while Omit is best when you need most properties but want to remove a few. For example, Pick<User, "id" | "name"> keeps only id and name, while Omit<User, "password"> keeps everything except password.
When should I use Partial vs Required in TypeScript?
Use Partial<T> when you need a type where all properties are optional, such as update functions that accept partial data. Use Required<T> when you need to ensure all properties are provided, such as config objects after merging with defaults. Partial makes every property optional (?), while Required removes the optional modifier from every property.
How do I create custom utility types in TypeScript?
Custom utility types are built using mapped types, conditional types, and template literal types. A mapped type iterates over keys of a type and transforms each property. For example, type Readonly<T> = { readonly [P in keyof T]: T[P] } makes all properties read-only. Conditional types use the syntax T extends U ? X : Y to create types that depend on conditions. Combine these with infer, keyof, and generic constraints to build powerful reusable type transformations.
What is NoInfer in TypeScript used for?
NoInfer<T> blocks TypeScript from using one position to infer a generic type. It is useful when one argument should be the source of truth and another argument should be checked against that source instead of widening it. A common pattern is a typed config helper where the allowed keys come from one argument and a default value must be one of those exact keys.
Which TypeScript utility types should I learn first?
Start with Partial, Pick, Omit, Record, Exclude, Extract, ReturnType, Parameters, Awaited, and NoInfer. Those cover most API, form, config, function-wrapper, union-filtering, and async result patterns.
When should I use Awaited with ReturnType?
Use Awaited<ReturnType<typeof fn>> when fn is async or returns a Promise-like value and you need the resolved value type. This keeps typed API clients, React loaders, and service wrappers synchronized with the function implementation.

Generate and Inspect TypeScript API Types

Working with JSON APIs, configs, or test fixtures in TypeScript? Generate interfaces from sample JSON, then use utility types like Pick, Omit, and Partial to create safe request and response types.

Related Articles