es-toolkit
Version:
A state-of-the-art, high-performance JavaScript utility library with a small bundle size and strong type annotations.
22 lines • 1.02 kB
TypeScript
//#region src/types/DeepReadonly.d.ts
/**
* Makes all properties of `T` readonly recursively, unlike the built-in
* `Readonly` which only affects the first level.
*
* Arrays and tuples become readonly, and `Map`/`Set` become
* `ReadonlyMap`/`ReadonlySet`. Functions, `Date`, and `RegExp` pass through
* unchanged.
*
* @template T - The type to make deeply readonly.
*
* @example
* type State = { user: { name: string; tags: string[] } };
* type FrozenState = DeepReadonly<State>;
* // => { readonly user: { readonly name: string; readonly tags: readonly string[] } }
*
* declare const state: FrozenState;
* state.user.name = 'x'; // error: name is readonly
*/
type DeepReadonly<T> = T extends ((...args: any[]) => unknown) | Date | RegExp ? T : T extends ReadonlyMap<infer K, infer V> ? ReadonlyMap<DeepReadonly<K>, DeepReadonly<V>> : T extends ReadonlySet<infer U> ? ReadonlySet<DeepReadonly<U>> : T extends object ? { readonly [K in keyof T]: DeepReadonly<T[K]> } : T;
//#endregion
export { DeepReadonly };