TypeScript ships built-in utility types that transform existing types — Partial makes all properties optional, Pick/Omit select or exclude properties, Record constructs object types, and ReturnType/Parameters extract function signatures, all implemented using mapped and conditional types under the hood.
Partial<T> makes all optional, Required<T> makes all required, Readonly<T> makes all readonly — all implemented as mapped types with modifier operations.
Pick<T, K> selects specific properties, Omit<T, K> removes them — complementary tools for creating type subsets.
ReturnType<T> extracts return type, Parameters<T> extracts parameter tuple — use typeof to get the type of a function value.
Exclude removes types from a union, Extract keeps matching types, NonNullable removes null/undefined — all use distributive conditional types.
Utility types compose: Partial<Omit<User, 'id'>> for update payloads, Readonly<Pick<User, 'name'>> for immutable subsets.
TypeScript's built-in utility types are generic types that transform other types. They're implemented using mapped types and conditional types, so understanding how they work helps you write custom utilities.
Partial<T> — Makes all properties optional:
type Partial<T> = { [K in keyof T]?: T[K] };
interface User { name: string; age: number; }
type PartialUser = Partial<User>; // { name?: string; age?: number; }Common use: update functions that accept a subset of properties: function updateUser(id: string, updates: Partial<User>).
Required<T> — Makes all properties required (removes ?):
type Required<T> = { [K in keyof T]-?: T[K] };The -? removes the optional modifier. Useful when you need to ensure all fields are present (e.g., after validation).
Readonly<T> — Makes all properties readonly:
type Readonly<T> = { readonly [K in keyof T]: T[K] };Prevents accidental mutation. Note: this is shallow — nested objects are still mutable. For deep immutability, you need a custom DeepReadonly or as const.
Pick<T, K> — Select specific properties:
type Pick<T, K extends keyof T> = { [P in K]: T[P] };
type UserName = Pick<User, 'name'>; // { name: string }
type UserNameAge = Pick<User, 'name' | 'age'>;Omit<T, K> — Remove specific properties:
type Omit<T, K extends keyof any> = Pick<T, Exclude<keyof T, K>>;
type UserWithoutAge = Omit<User, 'age'>; // { name: string }Pick and Omit are complementary — use whichever results in a shorter union of keys.
Record<K, V> — Create an object type with keys K and values V:
type Record<K extends keyof any, V> = { [P in K]: V };
type Scores = Record<string, number>; // { [key: string]: number }
type StatusMap = Record<'active' | 'inactive', User[]>;Record is the type-safe way to describe dictionaries and lookup objects.
ReturnType<T> — Extract a function's return type:
type ReturnType<T extends (...args: any) => any> = T extends (...args: any) => infer R ? R : any;
function getUser() { return { name: 'Alice', age: 30 }; }
type User = ReturnType<typeof getUser>; // { name: string; age: number }Parameters<T> — Extract function parameters as a tuple:
type Parameters<T extends (...args: any) => any> = T extends (...args: infer P) => any ? P : never;
type Params = Parameters<typeof getUser>; // []ConstructorParameters<T> and InstanceType<T> do the same for class constructors.
Exclude<T, U> — Remove types from T that are assignable to U:
type Exclude<T, U> = T extends U ? never : T;
type Result = Exclude<'a' | 'b' | 'c', 'a'>; // 'b' | 'c'Extract<T, U> — Keep only types from T assignable to U:
type Extract<T, U> = T extends U ? T : never;
type Result = Extract<string | number | boolean, number | boolean>; // number | booleanNonNullable<T> — Remove null and undefined:
type NonNullable<T> = T & {}; // equivalent to Exclude<T, null | undefined>
type Result = NonNullable<string | null | undefined>; // stringAwaited<T> — Unwrap Promise types (recursively):
type Result = Awaited<Promise<Promise<string>>>; // stringUtility types compose together:
// Optional update payload without the id field
type UserUpdate = Partial<Omit<User, 'id'>>;
// Readonly version of only name and email
type ReadonlyNameEmail = Readonly<Pick<User, 'name' | 'email'>>;Partial makes properties optional for update patterns. Pick/Omit select or exclude properties. Record constructs typed dictionaries. ReturnType and Parameters extract function signatures using conditional types with infer. Exclude/Extract filter union types. These are all implemented using mapped types and conditional types — understanding the implementation helps you write custom utilities.
Fun Fact
NonNullable<T> was simplified from Exclude<T, null | undefined> to T & {} in TypeScript 4.8. The empty object intersection ({}) excludes null and undefined because null and undefined are not assignable to {} — it's a clever hack that's more performant than the conditional type version.