---
title: "TypeScript Utility Types Cheatsheet"
slug: "typescript-utility-types"
category: "cheatsheets"
tags: ["cheatsheets", "typescript", "types", "reference", "frontend", "backend"]
status: "stable"
last_updated: 2026-05-14
summary: "TypeScript utility types: Pick, Omit, Partial, Required, Readonly, Record, Exclude, Extract, NonNullable, ReturnType, and Awaited with examples."
related:
  [
    "[[coding/typescript-utility-types]]",
    "[[coding/typescript-types-vs-interfaces]]",
    "[[coding/typescript-strict-mode]]",
    "[[coding/typescript-narrowing]]",
    "[[coding/typescript]]",
    "[[cheatsheets/index|Cheatsheets]]",
  ]
---

## Overview

TypeScript ships a set of built-in generic utility types that transform existing types into new ones. This card is the lookup table; the rationale and composition patterns live in [[coding/typescript-utility-types]].

All examples reference this base type:

```typescript
type User = {
  id: number;
  name: string;
  email: string;
  role: "admin" | "user";
  createdAt: Date;
};
```

## Object shape utilities

Modify which fields exist or are required.

| Type | Signature | Example result |
| --- | --- | --- |
| `Partial<T>` | All fields optional. | `Partial<User>`: every field becomes `?`. |
| `Required<T>` | All fields required (removes `?`). | `Required<Partial<User>>`: restores `User`. |
| `Readonly<T>` | All fields readonly. | `Readonly<User>`: no reassignment. |
| `Pick<T, K>` | Keep only listed keys. | `Pick<User, "id" \| "name">`: `{id, name}`. |
| `Omit<T, K>` | Remove listed keys. | `Omit<User, "createdAt">`: User without `createdAt`. |
| `Record<K, V>` | Map from keys `K` to values `V`. | `Record<string, User>`: string-keyed user map. |

```typescript
// Use Partial for update payloads
type UpdateUser = Partial<Omit<User, "id" | "createdAt">>;

// Use Pick for API response shapes
type UserSummary = Pick<User, "id" | "name" | "role">;

// Use Record for lookup tables
const usersByEmail: Record<string, User> = {};
```

## Union manipulation

Filter and transform union types.

| Type | Signature | Example result |
| --- | --- | --- |
| `Exclude<T, U>` | Remove from `T` the members assignable to `U`. | `Exclude<"a" \| "b" \| "c", "a">` → `"b" \| "c"`. |
| `Extract<T, U>` | Keep only members of `T` assignable to `U`. | `Extract<string \| number, string>` → `string`. |
| `NonNullable<T>` | Remove `null` and `undefined` from `T`. | `NonNullable<string \| null>` → `string`. |

```typescript
type Role = "admin" | "user" | "guest";
type PrivilegedRole = Exclude<Role, "guest">; // "admin" | "user"

type MaybeUser = User | null | undefined;
type DefiniteUser = NonNullable<MaybeUser>; // User
```

## Function utilities

Introspect function types without touching the implementation.

| Type | What it extracts | Example |
| --- | --- | --- |
| `ReturnType<T>` | Return type of function `T`. | `ReturnType<typeof getUser>` → `User`. |
| `Parameters<T>` | Parameter types as a tuple. | `Parameters<typeof createUser>` → `[string, string]`. |
| `ConstructorParameters<T>` | Constructor parameter types. | `ConstructorParameters<typeof Date>` → `[string \| number \| ...]`. |
| `InstanceType<T>` | Instance type from a constructor. | `InstanceType<typeof Map>` → `Map<unknown, unknown>`. |

```typescript
function fetchUser(id: number, options?: { cache: boolean }): Promise<User> { ... }

type FetchArgs = Parameters<typeof fetchUser>;    // [number, {cache: boolean}?]
type FetchResult = ReturnType<typeof fetchUser>;  // Promise<User>
```

## Async utilities

| Type | What it does | Example |
| --- | --- | --- |
| `Awaited<T>` | Recursively unwrap `Promise<T>`. | `Awaited<Promise<Promise<string>>>` → `string`. |

```typescript
async function loadUser(id: number): Promise<User> { ... }

type LoadResult = Awaited<ReturnType<typeof loadUser>>; // User
```

`Awaited` is the correct way to type async function results without manually stripping `Promise<>`.

## String and template utilities

| Type | What it does | Example |
| --- | --- | --- |
| `Uppercase<S>` | Uppercase all characters. | `Uppercase<"hello">` → `"HELLO"`. |
| `Lowercase<S>` | Lowercase all characters. | `Lowercase<"HELLO">` → `"hello"`. |
| `Capitalize<S>` | Capitalize first character. | `Capitalize<"hello">` → `"Hello"`. |
| `Uncapitalize<S>` | Lowercase first character. | `Uncapitalize<"Hello">` → `"hello"`. |

```typescript
// Generate event handler names from event types
type EventName = "click" | "focus" | "blur";
type HandlerName = `on${Capitalize<EventName>}`; // "onClick" | "onFocus" | "onBlur"
```

## Common gotchas

- `Partial<T>` makes all nested fields optional at the top level only. For deep partial, write a recursive utility type or use a library.
- `Omit<T, K>` does not check that `K` is a key of `T` in all TypeScript versions before 4.9. A typo silently returns `T` unchanged. Use `Pick` when you want strictness on the key list.
- `Record<string, User>` marks every string key as present; accessing a missing key has type `User`, not `User | undefined`. Use `Record<string, User | undefined>` or enable `noUncheckedIndexedAccess` in `tsconfig`.
- `ReturnType` of an overloaded function returns the last overload signature only. Introspect overloaded functions with explicit type annotations instead.
- `Exclude` works on union members, not on object properties. To remove a property, use `Omit`. To remove a union member, use `Exclude`.
- `Awaited` unwraps all nested promises recursively. `Awaited<Promise<Promise<string>>>` is `string`, not `Promise<string>`.

## Related

- [[coding/typescript-utility-types]]
- [[coding/typescript-types-vs-interfaces]]
- [[coding/typescript-strict-mode]]
- [[coding/typescript-narrowing]]
- [[coding/typescript]]
- [[cheatsheets/index|Cheatsheets]]
