Web Development
TypeScript
Subjective
Oct 04, 2025
How do you create a deep readonly type that works recursively?
Detailed Explanation
Deep readonly types recursively apply readonly to all nested properties and arrays.
Basic Deep Readonly:
type DeepReadonly = {
readonly [P in keyof T]: T[P] extends object
? T[P] extends Function
? T[P]
: DeepReadonly
: T[P];
};
interface User {
id: number;
profile: {
name: string;
settings: {
theme: string;
notifications: boolean;
};
};
hobbies: string[];
}
type ReadonlyUser = DeepReadonly;
// All properties become readonly recursively
Advanced Version with Array Handling:
type DeepReadonlyAdvanced = T extends (infer R)[]
? ReadonlyArray>
: T extends Function
? T
: T extends object
? { readonly [K in keyof T]: DeepReadonlyAdvanced }
: T;
type TestArray = DeepReadonlyAdvanced<{
items: {
id: number;
tags: string[];
}[];
}>;
// { readonly items: ReadonlyArray<{ readonly id: number; readonly tags: ReadonlyArray }> }
Practical Implementation:
function deepFreeze(obj: T): DeepReadonly {
Object.getOwnPropertyNames(obj).forEach(prop => {
const value = (obj as any)[prop];
if (value && typeof value === 'object') {
deepFreeze(value);
}
});
return Object.freeze(obj) as DeepReadonly;
}
const mutableUser: User = {
id: 1,
profile: {
name: 'John',
settings: { theme: 'dark', notifications: true }
},
hobbies: ['reading', 'coding']
};
const immutableUser = deepFreeze(mutableUser);
// immutableUser.profile.name = 'Jane'; // Error: readonly
Benefits:
• Prevents accidental mutations
• Ensures immutability at compile time
• Works with nested objects and arrays
• Provides runtime immutability when combined with Object.freeze.
Discussion (0)
No comments yet. Be the first to share your thoughts!
Share Your Thoughts