Technology · TypeScript

TypeScript Utility Types

Quick reference for Partial, Pick, Omit, Record, and other built-in utility types in TypeScript.

TL;DR
  1. 01Transform existing types without rewriting them from scratch.
  2. 02Build new types from object keys and values.
  3. 03Extract pieces from function and promise return types.

Object Transforms

  • Use Partial<T> to make every property in a type optional.
    interface User { id: number; name: string }
    type Draft = Partial<User>;
    const d: Draft = { name: "Sam" };
  • Use Required<T> to make every property in a type required.
    type Complete = Required<Draft>;
  • Use Readonly<T> to make every property read-only and unchangeable.
    const user: Readonly<User> = { id: 1, name: "Sam" };
    // user.name = "Jo"; // error
  • Combine these with other utilities to build update or patch objects.
  • Apply Partial when working with form drafts or incremental updates.

Pick and Omit

  • Use Pick<T, K> to select specific properties from a type by key.
    interface User { id: number; name: string; email: string }
    type Preview = Pick<User, "id" | "name">;
  • Use Omit<T, K> to remove specific properties from a type by key.
    type CreateUser = Omit<User, "id">;
  • Pass a union of keys to pick or omit multiple properties at once.
  • Combine Pick and Omit to build focused types for components or APIs.
  • These utilities help you avoid duplicating large object type definitions.

Record and Key Maps

  • Use Record<K, T> to build an object type with known keys and value type.
    type Roles = "admin" | "editor" | "viewer";
    const perms: Record<Roles, boolean> = {
      admin: true, editor: true, viewer: false
    };
  • Pass a union of strings as keys for a typed map of fixed entries.
  • Use Record<string, T> for an object with any string keys and uniform values.
    const cache: Record<string, number> = {};
  • Record works well for lookup tables, configuration maps, and dictionaries.
  • Pair Record with literal union types for fully type-safe enums.

Function and Promise

  • Use ReturnType<T> to extract the return type of a function type.
    function getUser() { return { id: 1, name: "Sam" }; }
    type User = ReturnType<typeof getUser>;
  • Use Parameters<T> to extract function parameters as a tuple type.
    type Args = Parameters<typeof getUser>;
  • Use Awaited<T> to unwrap the resolved value from a Promise type.
    type Result = Awaited<Promise<string>>; // string
  • Combine these to type wrappers and higher-order functions cleanly.
  • Use ConstructorParameters<T> to extract constructor arguments from a class.

String Manipulation

  • Use Uppercase<T> and Lowercase<T> to transform string literal types.
    type Yell = Uppercase<"hello">; // "HELLO"
    type Quiet = Lowercase<"HELLO">; // "hello"
  • Use Capitalize<T> to make the first letter of a literal uppercase.
    type Greeting = Capitalize<"hello">; // "Hello"
  • Use Uncapitalize<T> to make the first letter of a literal lowercase.
  • Combine these with template literal types for advanced string typing.
    type Event<T extends string> = `on${Capitalize<T>}`;
    type ClickEvent = Event<"click">; // "onClick"
  • Apply them when building type-safe event names, keys, or API routes.

Tip: Combine utility types like Partial<Pick<User, "name" | "email">> to build precise, reusable types in just one line.

Warning: Some utilities like Required can hide bugs when applied to types that intentionally allow undefined properties.

TypeScript Type NarrowingTypeScript Advanced Types