Utility Types

This section documents the current TypeScript release line as published at the official TypeScript documentation, which is the reference these pages are written and verified against. No specific patch version is pinned.

This content was generated with the assistance of AI and should be verified against the official documentation before being relied on in production, since TypeScript iterates quickly.

This section’s bibliography lists the reference material consulted while preparing these pages.

TypeScript ships a set of generic types in the global scope that transform other types: make every property optional, pull the return type out of a function, drop members from a union. They are ordinary mapped and conditional types — nothing magic — and the full list lives in Utility Types. This page groups them by what they operate on and shows the definition behind each. For how those definitions are built, see Type Manipulation; for the generic syntax they use, see Generics.

Object-shape utilities

These rework the property set of an object type. Partial, Required and Readonly flip a modifier on every property; Pick and Omit select or drop a subset of keys; Record builds a fresh object type from a key union and a value type.

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

// Partial<T> -- every property optional (patch objects)
function applyPatch(user: User, patch: Partial<User>): User {
  return { ...user, ...patch };
}
applyPatch({ id: 1, name: "Ada", email: "a@x.io" }, { name: "Ada L." });

// Required<T> -- every property required (undo optionality)
interface Config { host?: string; port?: number; }
const resolved: Required<Config> = { host: "localhost", port: 5432 };

// Readonly<T> -- every property read-only (compile-time freeze)
const frozen: Readonly<User> = { id: 1, name: "Ada", email: "a@x.io" };
// frozen.name = "x"; // Error: Cannot assign to 'name' because it is a read-only property.

// Pick<T, Keys> -- keep only the listed keys
type UserPreview = Pick<User, "id" | "name">;   // { id: number; name: string }

// Omit<T, Keys> -- drop the listed keys
type UserDraft = Omit<User, "id">;              // { name: string; email: string }

// Record<Keys, Value> -- object type with those keys, each of Value
type RolePermissions = Record<"admin" | "editor" | "viewer", boolean>;
const perms: RolePermissions = { admin: true, editor: true, viewer: false };

Pick keys must exist on T; Omit keys are not constrained, which makes Omit convenient but slightly looser. See Pick, Omit and Record. For the interface versus type-alias choice these produce, see Objects and Interfaces.

Union algebra

Exclude and Extract filter a union member by member; NonNullable is the special case that removes null and undefined.

type Shape = "circle" | "square" | "triangle" | null;

type NamedShape = Exclude<Shape, null>;            // "circle" | "square" | "triangle"
type Corners = Exclude<NamedShape, "circle">;      // "square" | "triangle"
type OnlyCircle = Extract<NamedShape, "circle" | "hexagon">; // "circle"

type MaybeName = string | null | undefined;
type Name = NonNullable<MaybeName>;                // string

// Extract also works structurally: keep union members assignable to a shape
type Events =
  | { kind: "click"; x: number; y: number }
  | { kind: "key"; code: string }
  | { kind: "scroll"; dy: number };
type PointerEvents = Extract<Events, { x: number }>; // the "click" member

Exclude<T, U> keeps the members of T not assignable to U; Extract<T, U> keeps the ones that are. Docs: Exclude, Extract and NonNullable.

Function and class reflection

These read types back out of functions, constructors and promises. Each is a conditional type with an infer clause.

function createUser(name: string, age: number, admin = false) {
  return { name, age, admin, createdAt: Date.now() };
}

type CreateArgs = Parameters<typeof createUser>; // [name: string, age: number, admin?: boolean]
type NewUser = ReturnType<typeof createUser>;    // { name: string; age: number; admin: boolean; createdAt: number }

class Connection {
  constructor(public host: string, public port: number) {}
  query(sql: string) { return [] as unknown[]; }
}

type ConnArgs = ConstructorParameters<typeof Connection>; // [host: string, port: number]
type Conn = InstanceType<typeof Connection>;              // Connection

// this-parameter helpers
interface Account { name: string; }
function describe(this: Account, prefix: string): string {
  return `${prefix}: ${this.name}`;
}
type DescribeThis = ThisParameterType<typeof describe>;  // Account
type DescribeBound = OmitThisParameter<typeof describe>; // (prefix: string) => string

// Awaited<T> -- unwrap Promise (recursively), mirrors `await`
type A = Awaited<Promise<string>>;              // string
type B = Awaited<Promise<Promise<number>>>;     // number
type C = Awaited<ReturnType<typeof fetch>>;     // Response

Awaited is what async functions and Promise.all use internally; reach for it whenever you name the resolved type of a promise. See Parameters, ReturnType, InstanceType and Awaited. Promise-heavy code is covered in Async, Iterators and Generators.

String-literal utilities and inference control

Uppercase, Lowercase, Capitalize and Uncapitalize are intrinsic types that transform string literal types — most useful inside the template literal types described in Type Manipulation.

type Method = "get" | "post" | "delete";
type ScreamMethod = Uppercase<Method>;            // "GET" | "POST" | "DELETE"
type LowerMethod = Lowercase<"GET" | "POST">;     // "get" | "post"

type DomEvent = "click" | "focus";
type Handler = `on${Capitalize<DomEvent>}`;       // "onClick" | "onFocus"
type Field = Uncapitalize<"FirstName" | "LastName">; // "firstName" | "lastName"

NoInfer<T>

NoInfer<T> blocks a type parameter from being inferred from the position it wraps, so inference is driven only by the other arguments.

function paint<C extends string>(palette: C[], selected: NoInfer<C>) {
  /* ... */
}

paint(["red", "green", "blue"], "green"); // ok
paint(["red", "green", "blue"], "pink");  // Error: "pink" is not assignable to "red" | "green" | "blue"
// Without NoInfer, `selected: "pink"` would widen C to include "pink" and the call would compile.

See NoInfer. It pairs well with the const type parameters from Generics.

How each is implemented

Every utility above is one line of the machinery from Type Manipulation. The object-shape helpers are homomorphic mapped types; the union helpers are distributive conditional types; the reflection helpers are conditional types with infer:

// Standard library definitions (from lib.es5.d.ts), simplified:
type Partial<T>  = { [P in keyof T]?: T[P] };
type Required<T> = { [P in keyof T]-?: T[P] };
type Readonly<T> = { readonly [P in keyof T]: T[P] };

type Pick<T, K extends keyof T> = { [P in K]: T[P] };
type Record<K extends keyof any, T> = { [P in K]: T };

type Exclude<T, U> = T extends U ? never : T;
type Extract<T, U> = T extends U ? T : never;
type NonNullable<T> = T extends null | undefined ? never : T;

type Parameters<T extends (...a: any) => any> =
  T extends (...a: infer P) => any ? P : never;
type ReturnType<T extends (...a: any) => any> =
  T extends (...a: any) => infer R ? R : never;

Omit is the one composite: type Omit<T, K> = Pick<T, Exclude<keyof T, K>> — pick every key except the excluded ones. Because Exclude distributes over unions, Exclude<"a" | "b" | "c", "b"> is evaluated for each member separately and the survivors are unioned back together. Uppercase and its three siblings are the exception: they are compiler intrinsics with no TypeScript-level definition.

Keeping two values in sync with Record

A Record key union is checked for completeness, so deriving one table’s type from a single source union keeps every table over that union aligned. Add a member and each Record fails to compile until its object literal is updated.

const LOCALES = ["en", "es", "fr"] as const;
type Locale = (typeof LOCALES)[number];          // "en" | "es" | "fr"

// Every locale must have a greeting -- a missing key is a compile error.
const greetings: Record<Locale, string> = {
  en: "Hello",
  es: "Hola",
  fr: "Bonjour",
};

// Same union, second table stays in step.
const flags: Record<Locale, string> = { en: "GB", es: "ES", fr: "FR" };

Summary

Utility Transforms

Partial<T>

Every property of T optional

Required<T>

Every property of T required

Readonly<T>

Every property of T read-only

Record<K, V>

Object type with keys K, each value V

Pick<T, K>

Object type with only the keys K of T

Omit<T, K>

T without the keys K

Exclude<T, U>

Union T without members assignable to U

Extract<T, U>

Union T keeping only members assignable to U

NonNullable<T>

T without null and undefined

Parameters<F>

Tuple of `F’s parameter types

ConstructorParameters<C>

Tuple of `C’s constructor parameter types

ReturnType<F>

`F’s return type

InstanceType<C>

Instance type produced by new C

ThisParameterType<F>

Type of F’s `this parameter

OmitThisParameter<F>

F with its this parameter removed

Awaited<T>

Resolved type of a Promise (recursive)

Uppercase<S> / Lowercase<S>

String literal S upper- / lower-cased

Capitalize<S> / Uncapitalize<S>

First character of S up- / down-cased

NoInfer<T>

T, but excluded from type inference

The handbook page Utility Types is the authoritative list and tracks additions each release.