A mapped type creates a new type by transforming each property of an existing type. It uses syntax like { [K in keyof T]: ... } to loop over keys.
Click to reveal answer
intermediate
How can you apply a transformation deeply to nested objects using mapped types?
You can use recursive mapped types that check if a property is an object and then apply the mapped type again to that property, enabling deep transformations.
Click to reveal answer
advanced
Explain the purpose of the infer keyword in deep mapped types.
infer helps extract types inside conditional types. It can be used to capture inner types during recursion for deep transformations.
Click to reveal answer
intermediate
What does this TypeScript type do?
type DeepReadonly<T> = { readonly [K in keyof T]: T[K] extends object ? DeepReadonly<T[K]> : T[K] };
It makes all properties of T deeply readonly, meaning nested objects' properties are also readonly recursively.
Click to reveal answer
intermediate
Why do we need to check if a property is an object before applying deep mapped types?
Because primitive types like string or number should not be transformed recursively. Checking prevents errors and infinite recursion.
Click to reveal answer
What does keyof T represent in a mapped type?
AA primitive type
BAll values of type T
CA function in T
DAll keys of type T
✗ Incorrect
keyof T is a union of all property names (keys) of type T.
Which TypeScript feature allows a mapped type to apply itself recursively?
AEnums
BConditional types
CInterfaces
DType assertions
✗ Incorrect
Conditional types let you check if a property is an object and then apply the mapped type recursively.
What is the main risk if you don't check for object types in deep mapped types?
AInfinite recursion
BSyntax error
CTypeScript crashes
DNo effect
✗ Incorrect
Without checking, recursion can continue infinitely causing errors.
What does the readonly modifier do in a mapped type?
AMakes properties optional
BDeletes properties
CPrevents properties from being changed
DChanges property types
✗ Incorrect
readonly makes properties immutable after initialization.
Which syntax correctly defines a mapped type?
A{ [K in keyof T]: T[K] }
Bfunction map(T) { return T; }
Cinterface Mapped<T> {}
Dtype Mapped = T[]
✗ Incorrect
Mapped types use { [K in keyof T]: ... } syntax to transform properties.
Describe how to create a deep transformation mapped type in TypeScript.
Think about looping over keys and applying the type again if the property is an object.
You got /4 concepts.
Explain why deep mapped types are useful in real-world TypeScript projects.
Consider how nested data structures benefit from consistent type changes.
You got /4 concepts.
Practice
(1/5)
1.
What is the main purpose of a mapped type in TypeScript?
easy
A. To create a new type by transforming each property of an existing type
B. To execute functions asynchronously
C. To define runtime values for variables
D. To handle errors in promises
Solution
Step 1: Understand mapped types
Mapped types create new types by applying transformations to each property of an existing type.
Step 2: Compare options
Only To create a new type by transforming each property of an existing type describes this behavior correctly; others relate to runtime or async concepts.
Final Answer:
To create a new type by transforming each property of an existing type -> Option A
Quick Check:
Mapped type = transform properties [OK]
Hint: Mapped types change keys' types one by one [OK]
Common Mistakes:
Confusing mapped types with runtime functions
Thinking mapped types handle async code
Mixing mapped types with error handling
2.
Which of the following is the correct syntax to define a simple mapped type that makes all properties of T optional?
type PartialType = ?
easy
A. type PartialType<T> = { [P in keyof T]: T[P] }
B. type PartialType<T> = { [P in keyof T]: Optional }
C. type PartialType<T> = { [P in keyof T]?: T[P] }
D. type PartialType<T> = { [P: string]: T }
Solution
Step 1: Recall optional property syntax
Adding a question mark after the property name makes it optional in mapped types.
Step 2: Analyze options
type PartialType<T> = { [P in keyof T]?: T[P] } uses ?: correctly to make properties optional. type PartialType<T> = { [P in keyof T]: T[P] } keeps properties required. type PartialType<T> = { [P: string]: T } uses string keys incorrectly. type PartialType<T> = { [P in keyof T]: Optional } uses a non-existent Optional type.
Final Answer:
type PartialType<T> = { [P in keyof T]?: T[P] } -> Option C
Quick Check:
Optional properties use ? after key [OK]
Hint: Use ? after [P in keyof T] to make properties optional [OK]
Common Mistakes:
Forgetting the ? to mark properties optional
Using string index instead of keyof T
Assuming Optional<T> is built-in
3.
Given the following code, what is the type of DeepReadonly<User>?
type DeepReadonly<T> = {
readonly [P in keyof T]: T[P] extends object ? DeepReadonly<T[P]> : T[P]
};
interface User {
name: string;
address: {
city: string;
zip: number;
};
}
Hint: DeepReadonly adds readonly recursively to all nested properties [OK]
Common Mistakes:
Forgetting readonly on nested properties
Assuming only top-level properties are readonly
Confusing shallow and deep readonly
4.
Identify the error in this deep transformation mapped type:
type DeepPartial<T> = {
[P in keyof T]?: T[P] extends object ? DeepPartial<T[P]> : T[P];
}
medium
A. Incorrect use of semicolon instead of comma in mapped type
B. No error; the type is correct
C. The conditional type should check for primitives, not objects
D. Missing semicolon after the mapped property
Solution
Step 1: Check mapped type syntax
TypeScript object types, including mapped types, accept both commas and semicolons as separators, including trailing ones.
Step 2: Analyze the code
The syntax is valid, and the logic correctly makes properties optional while recursing DeepPartial on nested objects and preserving primitives.
Final Answer:
No error; the type is correct -> Option B
Quick Check:
Mapped types accept , or ; [OK]
Hint: Mapped types support , or ; separators [OK]
Common Mistakes:
Thinking semicolons are invalid in mapped types
Confusing separator rules from object literals
Overlooking recursive conditional logic
5.
How would you write a mapped type DeepNonNullable<T> that recursively removes null and undefined from all properties of T, including nested objects?
hard
A. type DeepNonNullable<T> = { [P in keyof T]: T[P] extends object ? DeepNonNullable<NonNullable<T[P]>> : NonNullable<T[P]> }
B. type DeepNonNullable<T> = { [P in keyof T]: NonNullable<T[P]> }
C. type DeepNonNullable<T> = { [P in keyof T]: T[P] extends object ? NonNullable<DeepNonNullable<T[P]>> : T[P] }
D. type DeepNonNullable<T> = { [P in keyof T]: T[P] extends object ? DeepNonNullable<T[P]> : T[P] }
Solution
Step 1: Understand NonNullable and recursion
We must remove null and undefined from each property, then recurse if the property is an object.
Step 2: Analyze options
type DeepNonNullable<T> = { [P in keyof T]: T[P] extends object ? DeepNonNullable<NonNullable<T[P]>> : NonNullable<T[P]> } first applies NonNullable to the property, then recursively applies DeepNonNullable to the cleaned type. This ensures null/undefined are removed at every level.
Final Answer:
type DeepNonNullable<T> = { [P in keyof T]: T[P] extends object ? DeepNonNullable<NonNullable<T[P]>> : NonNullable<T[P]> } -> Option A
Quick Check:
Remove null then recurse for objects [OK]
Hint: Apply NonNullable before recursion for deep cleaning [OK]
Common Mistakes:
Not applying NonNullable before recursion
Recursing without removing null/undefined
Confusing order of conditional checks
Recommended
Ready to prove it?
Pass the test and this pattern moves unknownstrongwhile earning +1 Grip toward your certificate.