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 typescript-utility-types.

All examples reference this base type:

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

Object shape utilities

Modify which fields exist or are required.

TypeSignatureExample 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.
// 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.

TypeSignatureExample 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.
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.

TypeWhat it extractsExample
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>.
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

TypeWhat it doesExample
Awaited<T>Recursively unwrap Promise<T>.Awaited<Promise<Promise<string>>>string.
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

TypeWhat it doesExample
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".
// 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>.