0
0
Typescriptprogramming~20 mins

Mapped type for deep transformations in Typescript - Practice Problems & Coding Challenges

Choose your learning style9 modes available
Challenge - 5 Problems
🎖️
Deep Mapped Types Master
Get all challenges correct to earn this badge!
Test your skills under time pressure!
Predict Output
intermediate
2:00remaining
Output of a deep readonly mapped type
What is the type of obj after applying the DeepReadonly mapped type to data?
Typescript
type DeepReadonly<T> = {
  readonly [K in keyof T]: T[K] extends object ? DeepReadonly<T[K]> : T[K]
};

const data = {
  name: "Alice",
  details: {
    age: 30,
    hobbies: ["reading", "hiking"]
  }
};

const obj: DeepReadonly<typeof data> = data;

// What happens if we try to assign obj.details.age = 31?
ATypeScript error: Property 'age' does not exist on type 'DeepReadonly<typeof data>'.
BRuntime error when assigning the value.
CTypeScript error: Cannot assign to 'age' because it is a read-only property.
DNo error, assignment works normally.
Attempts:
2 left
💡 Hint
Think about what 'readonly' means in TypeScript and how it applies recursively.
Predict Output
intermediate
2:00remaining
Output of a deep partial mapped type
Given the DeepPartial type below, what is the type of partialUser?
Typescript
type DeepPartial<T> = {
  [P in keyof T]?: T[P] extends object ? DeepPartial<T[P]> : T[P]
};

interface User {
  id: number;
  profile: {
    name: string;
    address: {
      city: string;
      zip: string;
    };
  };
}

const partialUser: DeepPartial<User> = {
  profile: {
    address: {
      city: "New York"
    }
  }
};
ApartialUser can have any subset of User properties, including nested ones, all optional.
BpartialUser must have all properties of User defined.
CpartialUser can only omit top-level properties, nested properties are required.
DpartialUser cannot omit any properties; all are required.
Attempts:
2 left
💡 Hint
Look at how the optional modifier and recursion are applied in the mapped type.
🔧 Debug
advanced
2:00remaining
Identify the error in a deep required mapped type
The following DeepRequired type is intended to make all properties required recursively. Which option correctly identifies the error in the code?
Typescript
type DeepRequired<T> = {
  [P in keyof T]-?: T[P] extends object ? DeepRequired<T[P]> : T[P];
};
AIt only works on top-level properties, not nested ones.
BIt causes infinite recursion on types like arrays or functions because they are objects too.
CIt does not remove optional modifiers from properties.
DIt causes a syntax error due to missing semicolon.
Attempts:
2 left
💡 Hint
Consider what types extend object in TypeScript and how that affects recursion.
📝 Syntax
advanced
2:00remaining
Which mapped type syntax is correct for deep transformation?
Which option correctly defines a mapped type that recursively makes all properties readonly?
Atype DeepReadonly<T> = { readonly [K in keyof T]: T[K] extends object ? DeepReadonly<T[K]> : T[K] };
Btype DeepReadonly<T> = { [K in keyof T]: readonly DeepReadonly<T[K]> };
Ctype DeepReadonly<T> = { readonly [K in keyof T]: DeepReadonly<T[K]> };
Dtype DeepReadonly<T> = { [K in keyof T]: T[K] extends object ? readonly DeepReadonly<T[K]> : T[K] };
Attempts:
2 left
💡 Hint
Remember to check the placement of 'readonly' and the conditional type.
🚀 Application
expert
3:00remaining
Create a mapped type to deeply transform all string properties to number
Which option defines a mapped type DeepStringToNumber that recursively changes all string properties to number, leaving other types unchanged?
Atype DeepStringToNumber<T> = { [K in keyof T]: T[K] extends object ? DeepStringToNumber<T[K]> : number };
Btype DeepStringToNumber<T> = { [K in keyof T]: T[K] extends object ? DeepStringToNumber<T[K]> : T[K] extends string ? number : T[K] };
Ctype DeepStringToNumber<T> = { [K in keyof T]: T[K] extends string ? number : T[K] };
Dtype DeepStringToNumber<T> = { [K in keyof T]: T[K] extends string ? number : T[K] extends object ? DeepStringToNumber<T[K]> : T[K] };
Attempts:
2 left
💡 Hint
Check the order of conditional checks to handle strings before objects or vice versa.