typescript
TypeScript Utility Type Patterns
Common TypeScript utility types for everyday development: DeepPartial, RequireAtLeastOne, and more.
#types
#generics
#patterns
A collection of useful utility types that extend TypeScript’s built-in utilities.
DeepPartial
Makes all properties optional recursively:
type DeepPartial<T> = {
[P in keyof T]?: T[P] extends object ? DeepPartial<T[P]> : T[P];
};
// Usage
interface Config {
server: { host: string; port: number };
features: { dark: boolean };
}
const partial: DeepPartial<Config> = {
server: { port: 3000 } // host is optional
};
RequireAtLeastOne
Requires at least one property from a set:
type RequireAtLeastOne<T, Keys extends keyof T = keyof T> = Pick<T, Exclude<keyof T, Keys>> &
{ [K in Keys]-?: Required<Pick<T, K>> & Partial<Pick<T, Exclude<Keys, K>>> }[Keys];
// Usage
interface Search {
query?: string;
tags?: string[];
author?: string;
}
type ValidSearch = RequireAtLeastOne<Search, 'query' | 'tags'>;
// Must have either query or tags (or both)
NonNullableFields
Makes specified fields non-nullable:
type NonNullableFields<T, K extends keyof T> = T & {
[P in K]-?: NonNullable<T[P]>;
};
// Usage
interface User {
id: string;
email: string | null;
name: string | null;
}
type VerifiedUser = NonNullableFields<User, 'email'>;
// email is now required and non-null
Prettify
Flattens intersected types for better IntelliSense:
type Prettify<T> = { [K in keyof T]: T[K] } & {};
// Usage
type Combined = { a: string } & { b: number };
type Pretty = Prettify<Combined>;
// Shows { a: string; b: number } instead of intersection
StrictOmit
Omit that enforces valid keys:
type StrictOmit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>;
// Unlike Omit, this errors if key doesn't exist
type User = { id: string; name: string };
type NoId = StrictOmit<User, 'id'>; // OK
// type Bad = StrictOmit<User, 'foo'>; // Error!