We now have the option as const which is a syntactically concise way of what @phil294 mentioned as the first option (nested readonly).
const a = {
b: 33,
c: [78, 99],
d:{e:{f:{g:true, h:{boom:'selecta'}}}}
} as const;
a.d.e.f.h.boom = 'respek'; //Cannot assign to 'boom' because it is a read-only property.ts(2540)
As an added bonus, you can make inputs to functions nested immutable using this trick:
type ImmutableObject<T> = {
readonly [K in keyof T]: Immutable<T[K]>;
}
export type Immutable<T> = {
readonly [K in keyof T]: T[K] extends Function ? T[K] : ImmutableObject<T[K]>;
}
so this would happen
const a = {
b: 33,
c: [78, 99],
d:{e:{f:{g:true, h:{boom:'selecta'}}}}
}
function mutateImmutable(input: Immutable<typeof a>) {
input.d.e.f.h.boom = 'respek'; //Cannot assign to 'boom' because it is a read-only property.ts(2540)
}