TypeScript Utility Types

A comprehensive reference for TypeScript built-in utility types like Partial, Pick, Omit, Record, and ReturnType.

TL;DR

  1. Transform object shapes with built-in Partial and Required helpers.
  2. Select or filter object keys using Pick and Omit utilities.
  3. Extract function return values automatically using the ReturnType utility.

Property Modifiers

    Partial<T>

    Transforms all properties of an object into optional fields.

    interface User { name: string; age: number; }
    type DraftUser = Partial<User>;
    // { name?: string; age?: number }
    Required<T>

    Converts all optional fields into strictly required properties.

    interface Props { color?: string; }
    type StrictProps = Required<Props>;
    // { color: string }
    Readonly<T>

    Prevents reassignment to any property on the object.

    type FrozenUser = Readonly<User>;
    const user: FrozenUser = { name: 'Ada', age: 32 };
    // user.age = 33; // Error: Cannot assign

Object Filtering

    Pick<T, K>

    Extracts a subset of properties matching the specified keys.

    interface Account {
      id: string;
      name: string;
      hash: string;
    }
    type PublicAccount = Pick<Account, 'id' | 'name'>;
    Omit<T, K>

    Constructs an object type omitting specified property keys.

    type SafeUser = Omit<Account, 'hash'>;
    // { id: string; name: string }
    Record<K, V>

    Maps a set of union keys to a uniform value type.

    type Role = 'admin' | 'user';
    const permissions: Record<Role, string[]> = {
      admin: ['read', 'write'],
      user: ['read']
    };

Union Manipulation

    Exclude<T, U>

    Removes members present in U from union type T.

    type Status = 'draft' | 'pending' | 'active';
    type FinalStatus = Exclude<Status, 'draft'>;
    // 'pending' | 'active'
    Extract<T, U>

    Selects only union members that are assignable to U.

    type Mixed = string | number | boolean;
    type TextOnly = Extract<Mixed, string>;
    // string
    NonNullable<T>

    Strips null and undefined from an existing union type.

    type Raw = string | null | undefined;
    type Clean = NonNullable<Raw>; // string

Function Introspection

    ReturnType<T>

    Extracts the return type of a function signature.

    function getUser() { return { id: '1', score: 100 }; }
    type UserInfo = ReturnType<typeof getUser>;
    Parameters<T>

    Obtains parameter types of a function as a tuple.

    function save(id: string, active: boolean) {}
    type SaveArgs = Parameters<typeof save>;
    // [id: string, active: boolean]
    Awaited<T>

    Unwraps Promise types recursively to get inner value.

    type AsyncData = Promise<Promise<string>>;
    type Value = Awaited<AsyncData>; // string

Custom Utility Types

    Mutable<T>

    Removes readonly modifiers using mapped type prefixing.

    type Mutable<T> = {
      -readonly [K in keyof T]: T[K];
    };
    type Writable = Mutable<Readonly<{ id: number }>>;
    Nullable<T>

    Creates a reusable nullish wrapper utility.

    type Nullable<T> = T | null | undefined;
    const token: Nullable<string> = null;
    DeepPartial<T>

    Recursively makes nested object properties optional.

    type DeepPartial<T> = T extends object ? {
      [P in keyof T]?: DeepPartial<T[P]>;
    } : T;

Tips

  1. Chain Partial<Pick<T, K>> when designing patch update payloads that permit editing only a subset of object fields.
  2. Use Record<K, V> with a strict string union for keys to mandate that every entry is accounted for.

Warnings

  1. Remember that Readonly<T> is compile-time only and does not invoke runtime Object.freeze() on underlying objects.
  2. Nesting deeply recursive custom <T> utility types can drastically degrade TypeScript editor responsiveness on large object trees.

In Practice

FAQ