Discover how one simple rule can replace dozens of repetitive type changes!
Why Mapped type with conditional types in Typescript? - Purpose & Use Cases
Imagine you have a big list of properties in an object, and you want to change the type of some properties based on certain rules. Doing this by hand means writing many lines of code for each property, checking conditions one by one.
Manually updating each property is slow and easy to mess up. If the object changes, you must rewrite or copy-paste code again. It's hard to keep track and fix mistakes, especially when the rules are complex.
Mapped types with conditional types let you write one smart rule that automatically changes property types based on conditions. This saves time, reduces errors, and keeps your code clean and easy to update.
type Manual = {
name: string;
age: number | null;
active: boolean;
};type Conditional<T> = {
[K in keyof T]: T[K] extends number ? string : T[K];
};You can create flexible, reusable types that adapt automatically to your data's shape and rules.
When building a form, you might want to convert all number fields to strings for input handling, but keep other fields unchanged. Mapped types with conditional types do this in one simple step.
Manual property updates are slow and error-prone.
Mapped types with conditional types automate type changes based on rules.
This makes your code cleaner, safer, and easier to maintain.
Practice
type Example<T> = { [K in keyof T]: T[K] extends string ? number : boolean }Solution
Step 1: Understand mapped types
Mapped types loop over each key in the original type to create a new type with transformed properties.Step 2: Apply conditional types
The conditional type checks if the property type extends string; if yes, it changes to number, else to boolean.Final Answer:
It creates a new type where string properties become number and others become boolean. -> Option AQuick Check:
Mapped + conditional changes types based on condition [OK]
- Thinking it removes properties instead of transforming them
- Assuming all types become string
- Confusing conditional type logic
Solution
Step 1: Check mapped type syntax
The correct syntax uses square brackets with 'in' keyword: [K in keyof T].Step 2: Verify conditional type usage
The conditional type is written as T[K] extends number ? string : boolean, which is correct.Final Answer:
type NewType<T> = { [K in keyof T]: T[K] extends number ? string : boolean } -> Option BQuick Check:
Mapped type syntax = [K in keyof T] [OK]
- Using 'K in T' instead of 'K in keyof T'
- Using 'K of keyof T' which is invalid
- Missing square brackets around K in mapped type
type Flags = { a: string; b: number; c: boolean };
type Result = { [K in keyof Flags]: Flags[K] extends number ? 'num' : 'not-num' };
const test: Result = { a: 'not-num', b: 'num', c: 'not-num' };What is the type of
test.b?Solution
Step 1: Analyze the mapped type Result
For each key in Flags, if the property type is number, Result's property is 'num', else 'not-num'.Step 2: Check property b in Flags
b is number, so Result['b'] is 'num'.Final Answer:
'num' -> Option CQuick Check:
Flags['b'] is number, so Result['b'] = 'num' [OK]
- Confusing original property type with mapped type
- Assuming test.b is number instead of 'num'
- Ignoring conditional type logic
type Fix<T> = { [P in keyof T]: T[P] extends string ? number : }Solution
Step 1: Check conditional type syntax
Conditional types require both true and false branches separated by colon.Step 2: Identify missing false branch
The code ends with ':' but no type after it, causing syntax error.Final Answer:
Missing type after colon in conditional type -> Option DQuick Check:
Conditional types need both branches [OK]
- Leaving out false branch in conditional type
- Misplacing square brackets in mapped type
- Thinking keyof is wrong here
Choose the correct mapped type:
Solution
Step 1: Understand key remapping in mapped types
Using 'as' allows filtering keys by condition, replacing keys with 'never' to omit them.Step 2: Check each option
type FilterStrings<T> = { [K in keyof T as T[K] extends string ? K : never]: T[K] } correctly uses 'as' with conditional to keep keys where T[K] extends string; others become never (excluded).Final Answer:
type FilterStrings<T> = { [K in keyof T as T[K] extends string ? K : never]: T[K] } -> Option AQuick Check:
Key remapping with 'as' filters keys [OK]
- Not using 'as' for key filtering
- Returning never as value instead of key
- Confusing key and value conditions
Ready to prove it?
Pass the test and this pattern moves unknown
