object-transforms
Readonly<T>
Marks every property of T as readonly, preventing reassignment after construction. Only enforced at compile-time — the underlying object is still mutable at runtime.
type Readonly<T> = { readonly [P in keyof T]: T[P] } Usage patterns
| Pattern | Purpose |
|---|---|
| Readonly<T> | Freeze all top-level properties at the type level |
| ReadonlyArray<T> | Companion built-in for immutable arrays |
| as const | Assertion that produces deep-readonly literal types |
| DeepReadonly<T> | Custom recursive variant — Readonly itself is shallow |
Examples
interface Point { x: number; y: number }
const p: Readonly<Point> = { x: 1, y: 2 };
p.x = 5; // Error Attempted mutation is caught at compile time
function freeze<T>(o: T): Readonly<T> {
return Object.freeze(o);
} Type-level counterpart of Object.freeze — but only shallow like Readonly
type Config = Readonly<{ endpoints: { api: string } }>;
const c: Config = { endpoints: { api: '' } };
c.endpoints.api = 'x'; // Allowed! Nested props remain mutable — Readonly is shallow
const tuple = [1, 2, 3] as const; // readonly [1, 2, 3] `as const` gives deep-readonly literal inference, unlike Readonly<T>
Gotcha
Readonly is shallow — nested objects/arrays stay writable. It also does not survive JSON.parse or spread copies; use `as const` or a DeepReadonly helper for true immutability.
Related utility types
Partial<T>
Constructs a type where every property of T is set to optional. Useful for representing update payloads, patch objects, and configuration overrides where all fields may be omitted.
Required<T>
Removes optionality from every property of T, producing a type where all fields must be present. The -? mapping modifier strips the ? flag from every key.
Record<K, V>
Creates an object type whose keys come from the union K and whose values all have type V. Useful for lookup tables, dictionaries, and enum-keyed maps.
Pick<T, K>
Builds a new type containing only the properties from T whose keys are in the union K. Ideal for narrowing large interfaces to the subset a function or component actually needs.
Omit<T, K>
Constructs a type by removing the properties in K from T. Unlike Pick, its K is not constrained to keyof T, so extra keys are silently ignored.
← All TS utility types · TypeScript vs JavaScript · any vs unknown vs never