DeepReadonly type
Makes every property and array read-only, at every depth: a frozen configuration, a state snapshot that must not be changed in place.
ts
import type { DeepReadonly } from 'utils';Signature
ts
export type DeepReadonly<T> = T extends (...arguments_: readonly never[]) => unknown
? T
: T extends readonly (infer Item)[]
? readonly DeepReadonly<Item>[]
: T extends object
? { readonly [K in keyof T]: DeepReadonly<T[K]> }
: T;Parameters
| Name | Description |
|---|---|
T | The type to protect. |
Example
ts
const DEFAULTS: DeepReadonly<Settings> = { chart: { series: [] } };Tests
Line coverage: 0 %.
- ✅ makes every depth read-only
- ✅ keeps functions whole
Source
src/types/deep-readonly.ts (on GitHub)
Source code
ts
/**
* Makes every property and array read-only, at every depth: a frozen configuration, a state snapshot that
* must not be changed in place.
*
* @template T - The type to protect.
* @example
* const DEFAULTS: DeepReadonly<Settings> = { chart: { series: [] } };
*/
export type DeepReadonly<T> = T extends (...arguments_: readonly never[]) => unknown
? T
: T extends readonly (infer Item)[]
? readonly DeepReadonly<Item>[]
: T extends object
? { readonly [K in keyof T]: DeepReadonly<T[K]> }
: T;Test file
ts
import type { DeepReadonly } from './deep-readonly';
describe('DeepReadonly', () => {
it('makes every depth read-only', () => {
expectTypeOf<DeepReadonly<{ a: { b: number[] } }>>().toEqualTypeOf<{
readonly a: { readonly b: readonly number[] };
}>();
});
it('keeps functions whole', () => {
expectTypeOf<DeepReadonly<{ f(value: number): string }>['f']>().toEqualTypeOf<(value: number) => string>();
});
});Keywords: deep, readonly, types, type