Implement a generic DeepMutable<T> which make every parameter of an object - and its sub-objects recursively - mutable. Learn recursive type definitions, readonly modifiers in this medium-level challenge on TypeScriptPro.
In this medium-level challenge, you'll implement DeepMutable<T> which recursively removes all readonly modifiers from every property of an object and its nested sub-objects, including arrays.
Implement a generic DeepMutable<T> which make every parameter of an object - and its sub-objects recursively - mutable.
For example
type X = {
readonly a: () => 1
readonly b: string
readonly c: {
readonly d: boolean
readonly e: {
readonly g: {
readonly h: {
readonly i: true
readonly j: "s"
}
readonly k: "hello"
}
}
}
}
type Expected = {
a: () => 1
b: string
c: {
d: boolean
e: {
g: {
h: {
i: true
j: "s"
}
k: "hello"
}
}
}
}
type Todo = DeepMutable<X> // should be same as `Expected`You can assume that we are only dealing with Objects in this challenge. Arrays, Functions, Classes and so on do not need to be taken into consideration. However, you can still challenge yourself by covering as many different cases as possible.
Change the following code to make the test cases pass (no type check errors).
Launch price: $19 $29
One-time payment. Lifetime access to all pro challenges.
type DeepMutable<T extends Record<string, any>> = {
-readonly [K in keyof T]: T[K] extends (...args: any[]) => any
? T[K]
: T[K] extends object
? DeepMutable<T[K]>
: T[K]
}How it works:
T extends Record<string, any> constrains the input to object types, which causes DeepMutable<'string'> and DeepMutable<0> to produce errors as expected-readonly [K in keyof T] uses the -readonly modifier to strip the readonly attribute from every property in the mapped typeT[K] extends (...args: any[]) => any checks if the property value is a function; if so, it is returned as-is since functions should not be recursed intoT[K] extends object checks if the value is an object (including arrays and tuples); if so, we recursively apply DeepMutable to strip readonly from nested propertiesT[K] unchangedreadonly ['hi', { readonly m: readonly ['hey'] }] becomes ['hi', { m: ['hey'] }])This challenge helps you understand the -readonly mapped type modifier and recursive type traversal, and how to apply these concepts in real-world scenarios.
This challenge is originally from here.
Get the latest TypeScript tips, tutorials, and updates delivered straight to your inbox.