What are Partial, Required, and Readonly utility types?
These three utility types transform the optionality and mutability of all properties in a type.
Partial<T> — makes every property optional (?):
interface User {
id: number;
name: string;
email: string;
}
type PartialUser = Partial<User>;
// { id?: number; name?: string; email?: string }
// Common use: update/patch functions
function updateUser(id: number, changes: Partial<User>): User {
return { ...findUser(id), ...changes };
}
Required<T> — makes every property required (removes ?):
interface Config {
host?: string;
port?: number;
timeout?: number;
}
type FinalizedConfig = Required<Config>;
// { host: string; port: number; timeout: number }
// After merging defaults — all fields are now guaranteed
function buildConfig(opts: Config): Required<Config> {
return { host: 'localhost', port: 3000, timeout: 5000, ...opts };
}
Readonly<T> — makes every property readonly:
const config: Readonly<Config> = { host: 'localhost', port: 3000 };
config.host = 'other'; // ❌ Error — readonly
// Deep readonly (not built-in, must define)
type DeepReadonly<T> = { readonly [K in keyof T]: DeepReadonly<T[K]> };
Readonly is only a compile-time protection — Object.freeze() is needed for runtime. Also note: ReadonlyArray<T> is the equivalent for arrays.