← All tasksTypeScript · Senior
DeepReadonly<T>
The built-in Readonly<T> protects only the first level: config.server.port = 1 still compiles. Write DeepReadonly<T> that makes every field readonly at any depth, including arrays and their elements.
Functions stay as they are, and primitives (string, number...) come back unchanged.
Ctrl+Enter runs the tests. Tab indents; to leave the editor with the keyboard, press Esc and then Tab. Your code is saved in this browser.
Tests (5)
Type tests are checked by the TypeScript compiler in strict mode. Expect<Equal<A, B>> passes when the types match exactly, and // @ts-expect-error passes when the next line does not compile. The first run downloads the compiler, so it takes a few seconds.
- types
type Config = { server: { port: number; tls: { cert: string } } }; type _ = Expect<Equal<DeepReadonly<Config>, { readonly server: { readonly port: number; readonly tls: { readonly cert: string } } }>>;
- types
type State = { items: { id: number }[] }; type _ = Expect<Equal<DeepReadonly<State>, { readonly items: readonly { readonly id: number }[] }>>;
- types
type Api = { load: (id: number) => string }; type _ = Expect<Equal<DeepReadonly<Api>, { readonly load: (id: number) => string }>>;
- types
type _ = Expect<Equal<DeepReadonly<string>, string>>; - types
const c = {} as DeepReadonly<{ a: { b: number } }>; // @ts-expect-error - nested fields are readonly too c.a.b = 2;