Skip to content

Instantly share code, notes, and snippets.

@milksense
Created July 27, 2021 03:51
Show Gist options
  • Save milksense/2d7e623d315c676d118ecd4ff76e96e3 to your computer and use it in GitHub Desktop.
Save milksense/2d7e623d315c676d118ecd4ff76e96e3 to your computer and use it in GitHub Desktop.
TypeScript type to return a deep readonly object (recursively)
export type Primitive = string | number | boolean | bigint | symbol | undefined | null;
export type Builtin = Primitive | Function | Date | Error | RegExp;
/**
* TypeScript type to return a deep readonly object (recursively).
*/
// prettier-ignore
export type DeepReadonly<T> = T extends Builtin
? T
: T extends Map<infer K, infer V>
? ReadonlyMap<DeepReadonly<K>, DeepReadonly<V>>
: T extends ReadonlyMap<infer K, infer V>
? ReadonlyMap<DeepReadonly<K>, DeepReadonly<V>>
: T extends WeakMap<infer K, infer V>
? WeakMap<DeepReadonly<K>, DeepReadonly<V>>
: T extends Set<infer U>
? ReadonlySet<DeepReadonly<U>>
: T extends ReadonlySet<infer U>
? ReadonlySet<DeepReadonly<U>>
: T extends WeakSet<infer U>
? WeakSet<DeepReadonly<U>>
: T extends Promise<infer U>
? Promise<DeepReadonly<U>>
: T extends (infer U)[]
? DeepReadonly<U>[]
: T extends {}
? { readonly [K in keyof T]: DeepReadonly<T[K]> }
: Readonly<T>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment