Skip to main content

Deep Readonly

introduction#

Implement a generic DeepReadonly<T> which make every parameter of an object - and its sub-objects recursively - readonly.

You can assume that we are only dealing with Objects in this challenge. Arrays, Functions, Classes and so on are no need to take into consideration. However, you can still challenge your self by covering different cases as many as possbile.

For example

ts
type X = {
x: {
a: 1
b: 'hi'
}
y: 'hey'
}
type Expected = {
readonly x: {
readonly a: 1
readonly b: 'hi'
}
readonly y: 'hey'
}
const todo: DeepReadonly<X> // should be same as `Expected`
ts
type X = {
x: {
a: 1
b: 'hi'
}
y: 'hey'
}
type Expected = {
readonly x: {
readonly a: 1
readonly b: 'hi'
}
readonly y: 'hey'
}
const todo: DeepReadonly<X> // should be same as `Expected`
View on GitHub

start point#

ts
/* _____________ Your Code Here _____________ */
 
type DeepReadonly<T> = any
 
/* _____________ Test Cases _____________ */
type cases = [
Expect<Equal<DeepReadonly<X>, Expected>>,
Type 'false' does not satisfy the constraint 'true'.2344Type 'false' does not satisfy the constraint 'true'.
]
 
type X = {
a: () => 22
b: string
c: {
d: boolean
e: {
g: {
h: {
i: true
j: 'string'
}
k: 'hello'
}
}
}
}
 
type Expected = {
readonly a: () => 22
readonly b: string
readonly c: {
readonly d: boolean
readonly e: {
readonly g: {
readonly h: {
readonly i: true
readonly j: 'string'
}
readonly k: 'hello'
}
}
}
}
Try
ts
/* _____________ Your Code Here _____________ */
 
type DeepReadonly<T> = any
 
/* _____________ Test Cases _____________ */
type cases = [
Expect<Equal<DeepReadonly<X>, Expected>>,
Type 'false' does not satisfy the constraint 'true'.2344Type 'false' does not satisfy the constraint 'true'.
]
 
type X = {
a: () => 22
b: string
c: {
d: boolean
e: {
g: {
h: {
i: true
j: 'string'
}
k: 'hello'
}
}
}
}
 
type Expected = {
readonly a: () => 22
readonly b: string
readonly c: {
readonly d: boolean
readonly e: {
readonly g: {
readonly h: {
readonly i: true
readonly j: 'string'
}
readonly k: 'hello'
}
}
}
}
Try
take the challenge

my solutions#

Spoiler warning // Click to reveal answer
ts
type DeepReadonly<T> = {
readonly [Key in keyof T]: keyof T[Key] extends undefined ? T[Key] : DeepReadonly<T[Key]>
}
Try
ts
type DeepReadonly<T> = {
readonly [Key in keyof T]: keyof T[Key] extends undefined ? T[Key] : DeepReadonly<T[Key]>
}
Try
view more solutions