TypeScript Utility Types
A comprehensive reference for TypeScript built-in utility types like Partial, Pick, Omit, Record, and ReturnType.
TL;DR
- Transform object shapes with built-in
PartialandRequiredhelpers. - Select or filter object keys using
PickandOmitutilities. - Extract function return values automatically using the
ReturnTypeutility.
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 assignObject 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>;
// stringNonNullable<T>Strips null and undefined from an existing union type.
type Raw = string | null | undefined;
type Clean = NonNullable<Raw>; // stringFunction 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>; // stringCustom 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
- Chain
Partial<Pick<T, K>>when designing patch update payloads that permit editing only a subset of object fields. - Use
Record<K, V>with a strict string union for keys to mandate that every entry is accounted for.
Warnings
- Remember that
Readonly<T>is compile-time only and does not invoke runtimeObject.freeze()on underlying objects. - Nesting deeply recursive custom
<T>utility types can drastically degrade TypeScript editor responsiveness on large object trees.
In Practice
Combines Pick, Partial, and Readonly to build type-safe database update operations.
- Declare a full database entity interface with identifiers and timestamps.
- Derive an update payload type omitting unmodifiable database keys.
- Make editable properties optional with Partial to support partial patches.
- Implement an update function accepting strictly validated patch objects.
interface Article {
readonly id: string;
title: string;
body: string;
}
type ArticlePatch = Partial<Omit<Article, 'id'>>;
function update(id: string, patch: ArticlePatch) {
console.log(`Update ${id}:`, patch);
}
update('art_10', { title: 'New Title' });FAQ
Pick creates a new type containing only the keys specified in K, which is best when you want a small slice of a larger model. Omit constructs a type by removing keys in K, which is ideal when you need almost the entire model minus a few private attributes.
Use Record whenever the keys belong to a finite union type like 'admin' | 'user'. Unlike a generic string index signature { [key: string]: V }, Record forces developers to provide definitions for every key enumerated in the union.
Pass typeof functionName into ReturnType. This lets TypeScript inspect the function's declaration and derive its resolved return type without requiring the external library to explicitly export the interface.
const loadData = () => ({ id: 1, name: 'Alice' });
type Data = ReturnType<typeof loadData>;Use a mapped type combined with modifier prefixes. For example, writing type Mutable uses the -readonly prefix to strip immutability constraints from every property on T.