Tutorial TypeScript JavaScript Developer Tools Cheat Sheet

Free TypeScript Utility Types Cheat Sheet Online — Interactive Reference for Developers

· 17 min read

TypeScript's built-in utility types are the power tools of the type system. They transform existing types into new shapes without duplicating declarations, enabling everything from partial form state to API response filtering. Yet many developers only know Partial and Pick, leaving the full toolkit largely unexplored. Understanding the complete set of utility types — and how to build your own — is the difference between fighting the compiler and making it work for you.

Our free interactive TypeScript utility types cheat sheet maps fifty-plus utilities across nine architectural categories. Each entry includes the type-level signature, a concise explanation, and a copyable code example. The Architect's Drafting Room aesthetic — deep blueprint slate background, technical grid overlay, TypeScript blue and copper accents, Chakra Petch display headings — turns type exploration into structural engineering. Everything runs in your browser. No compilation server, no signup, no data collection.

Why Utility Types Matter

TypeScript's type system is structural, not nominal. This means two types with the same shape are considered compatible regardless of where they were declared. While this reduces ceremony, it also means that type transformations — making properties optional, picking a subset, extracting return types — must be expressible at the type level. Utility types provide this expressivity.

Consider a typical application. You have a User interface with a dozen fields. Your API returns full User objects. Your profile form needs a Partial<User>. Your public profile page needs Pick<User, "id" | "name" | "avatar">. Your admin dashboard needs Omit<User, "passwordHash">. Without utility types, you would maintain four separate interfaces and pray they stay in sync. With utility types, you derive everything from a single source of truth.

Beyond the built-in utilities, the same patterns enable custom transformations. DeepPartial for nested optionality, branded types for nominal safety, UnionToIntersection for advanced composition — these are not exotic edge cases. They are everyday tools for teams working with complex type domains.

Basic Modifiers — Partial, Required, Readonly

The three foundational utility types modify the optionality and mutability of object properties. They are implemented using mapped types, which means you can build your own variants once you understand the pattern.

Partial<T>

Partial makes every property optional. It is the standard tool for update operations where you only provide the fields that changed.

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

type UserUpdate = Partial&lt;User&gt;;
// { id?: number; name?: string; email?: string }

const update: UserUpdate = { name: "Alice" };

Required<T>

Required strips the optionality modifier from every property. It is the inverse of Partial and useful when you have validated that all optional fields are now present.

interface Config {
  host?: string;
  port?: number;
}

type StrictConfig = Required&lt;Config&gt;;
// { host: string; port: number }

Readonly<T>

Readonly prevents reassignment of properties after object creation. It is essential for immutable state patterns and functional programming workflows.

interface Point {
  x: number;
  y: number;
}

type ImmutablePoint = Readonly&lt;Point&gt;;
const p: ImmutablePoint = { x: 0, y: 0 };
// p.x = 1; // Error: Cannot assign to 'x'

Mutable<T> (Custom)

TypeScript does not ship a built-in Mutable type, but it is trivial to construct using the minus modifier on readonly.

type Mutable&lt;T&gt; = { -readonly [K in keyof T]: T[K]; };

interface Frozen {
  readonly id: number;
  readonly name: string;
}

type Thawed = Mutable&lt;Frozen&gt;;
// { id: number; name: string }

Property Selection — Pick and Omit

When you need a subset of an existing type, Pick and Omit are the right tools. They are complementary: Pick selects specific keys to keep; Omit selects specific keys to remove.

Pick<T, K>

Pick creates a subtype containing only the keys you specify. It is the type-level equivalent of SQL SELECT.

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

type PublicUser = Pick&lt;User, "id" | "name"&gt;;
// { id: number; name: string }

Omit<T, K>

Omit creates a subtype by removing specific keys. It is ideal for stripping internal fields before sending data to the client.

type SafeUser = Omit&lt;User, "password"&gt;;
// { id: number; name: string; email: string }

Both Pick and Omit are implemented using mapped types and conditional types, which means they compose naturally with other utilities.

Key-Value Builders — Record and Mapped Types

Record<K, T> constructs an object type with uniform value types across all keys. It is the go-to type for dictionaries, lookup tables, and maps.

type PageInfo = { title: string; path: string };
type Pages = Record&lt;"home" | "about" | "contact", PageInfo&gt;;

const pages: Pages = {
  home: { title: "Home", path: "/" },
  about: { title: "About", path: "/about" },
  contact: { title: "Contact", path: "/contact" },
};

Behind Record lies the mapped type syntax [P in K]: T. This syntax is the engine for most custom utilities. You can remap keys, filter keys conditionally, and even transform key names using template literal types.

type Getters&lt;T&gt; = {
  [K in keyof T as `get${Capitalize&lt;string &amp; K&gt;}`]: () =&gt; T[K];
};

interface Person { name: string; age: number; }
type PersonGetters = Getters&lt;Person&gt;;
// { getName: () =&gt; string; getAge: () =&gt; number }

Set Operations on Unions — Exclude, Extract, NonNullable

Union types are the backbone of TypeScript's flexibility. The set operation utilities let you manipulate unions like mathematical sets.

Exclude<T, U>

Removes types from T that are assignable to U. This is set difference.

type Status = "pending" | "success" | "error" | "loading";
type FinalStatus = Exclude&lt;Status, "pending" | "loading"&gt;;
// "success" | "error"

Extract<T, U>

Extracts types from T that are assignable to U. This is set intersection.

type Mixed = string | number | boolean | Function;
type OnlyFunctions = Extract&lt;Mixed, Function&gt;;
// Function

NonNullable<T>

Removes null and undefined from a union. After a null check, this utility confirms the narrowed type.

type MaybeString = string | null | undefined;
type DefiniteString = NonNullable&lt;MaybeString&gt;;
// string

Function Introspection — Parameters, ReturnType, InstanceType

These utilities extract information from function and constructor types. They are indispensable for wrapper functions, proxies, and type-safe higher-order operations.

Parameters<T>

Extracts parameter types as a tuple.

type Fn = (a: string, b: number) =&gt; void;
type Args = Parameters&lt;Fn&gt;;
// [string, number]

ReturnType<T>

Extracts the return type of a function.

function createUser(name: string) {
  return { id: 1, name };
}

type User = ReturnType&lt;typeof createUser&gt;;
// { id: number; name: string }

InstanceType<T>

Extracts the instance type from a constructor.

class Container&lt;T&gt; {
  value!: T;
}

type StringContainer = InstanceType&lt;typeof Container&lt;string&gt;&gt;;
// Container&lt;string&gt;

String Manipulation at the Type Level

TypeScript 4.1 introduced intrinsic string manipulation types: Uppercase, Lowercase, Capitalize, and Uncapitalize. Combined with template literal types, they enable powerful string-derived type generation.

type EventName&lt;T extends string&gt; = `on${Capitalize&lt;T&gt;}`;
type ClickEvent = EventName&lt;"click"&gt;;
// "onClick"

type HttpMethod = "get" | "post";
type Endpoint = `/api/${HttpMethod}`;
// "/api/get" | "/api/post"

These types operate at compile time only. They generate new string literal types from existing ones, enabling type-safe routing, event naming, and API client generation.

Deep and Recursive Utilities

The built-in Partial, Required, and Readonly only operate at the top level. For nested objects, you need recursive custom utilities.

DeepPartial<T>

type DeepPartial&lt;T&gt; = {
  [P in keyof T]?: T[P] extends object ? DeepPartial&lt;T[P]&gt; : T[P];
};

interface Config {
  server: { host: string; port: number; ssl: { cert: string } };
}

type PartialConfig = DeepPartial&lt;Config&gt;;
// All properties at all depths are optional

DeepReadonly<T>

type DeepReadonly&lt;T&gt; = {
  readonly [P in keyof T]: T[P] extends object ? DeepReadonly&lt;T[P]&gt; : T[P];
};

interface Node {
  value: number;
  next?: Node;
}

type FrozenNode = DeepReadonly&lt;Node&gt;;
// All levels become readonly

These recursive types can hit recursion depth limits on deeply nested objects. For production use, consider adding a depth limit or using a library like type-fest.

Advanced Custom Patterns

Beyond the standard transformations, several custom patterns solve specific architectural problems.

Branded Types

Branded types create nominal typing within TypeScript's structural system. They prevent accidental mixing of semantically different values.

type Brand&lt;K, T&gt; = K &amp; { __brand: T };

type UserId = Brand&lt;number, "UserId"&gt;;
type OrderId = Brand&lt;number, "OrderId"&gt;;

function getUser(id: UserId) {}
const uid = 1 as UserId;
// getOrder(uid); // Error!

UnionToIntersection

Converts a union to an intersection using contravariant inference.

type UnionToIntersection&lt;U&gt; =
  (U extends any ? (k: U) =&gt; void : never) extends
  (k: infer I) =&gt; void ? I : never;

type U = { a: string } | { b: number };
type I = UnionToIntersection&lt;U&gt;;
// { a: string } &amp; { b: number }

OptionalKeys and RequiredKeys

type OptionalKeys&lt;T&gt; = {
  [K in keyof T]-?: {} extends Pick&lt;T, K&gt; ? K : never;
}[keyof T];

type RequiredKeys&lt;T&gt; = {
  [K in keyof T]-?: {} extends Pick&lt;T, K&gt; ? never : K;
}[keyof T];

Interactive TypeScript Utility Types Cheat Sheet

Reading about utility types is useful, but exploring them interactively is faster. Our free TypeScript Utility Types Cheat Sheet organizes every concept from this article into a searchable, filterable interface. Click any category tab to explore a territory of the type system. Use the search bar to find specific syntax instantly. Click the Copy button on any code block to grab the example and paste it into your editor.

The Architect's Drafting Room aesthetic makes the interface memorable. Deep blueprint slate background evokes a technical drawing studio. Faint grid lines suggest engineering precision. Drifting geometric shapes mark key waypoints. Each category receives a distinct accent color — gold for basic modifiers, teal for property selection, sky blue for key-value builders, violet for set operations, rose for function extraction, amber for this-related types, lime for string manipulation, copper for async and deep utilities, and slate for advanced patterns.

Related Developer Tools

TypeScript utility types are just one piece of the modern developer toolkit. Explore these related references to round out your workflow:

Conclusion

TypeScript utility types transform the type system from a static checker into a programmable design tool. From simple optionality changes with Partial and Required to deep recursive transformations and contravariant magic with UnionToIntersection, the expressive power available at the type level is remarkable. The key is to build your knowledge incrementally — master the built-in utilities first, then explore custom patterns as you encounter real problems that require them.

Keep the TypeScript Utility Types Cheat Sheet bookmarked. The next time you need to extract the return type of a function, make a nested object partially optional, or brand an ID to prevent type confusion, it will be one search away.

Found this useful? Check out our free developer tools or browse more articles.