Basic mapped type syntax in Typescript - Time & Space Complexity
We want to understand how the time it takes to create a new type changes as the number of keys grows.
How does the process of mapping over keys affect the work done?
Analyze the time complexity of the following code snippet.
type Options = 'width' | 'height' | 'color';
type MappedType<T extends string> = {
[K in T]: number;
};
type StyleOptions = MappedType<Options>;
This code creates a new type by mapping over a set of string keys and assigning each a number type.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: Mapping over each key in the union type
T. - How many times: Once for each key in the union (here 3 times for 'width', 'height', 'color').
As the number of keys increases, the work to create the mapped type grows proportionally.
| Input Size (n) | Approx. Operations |
|---|---|
| 3 | 3 |
| 10 | 10 |
| 100 | 100 |
Pattern observation: The work grows in a straight line with the number of keys.
Time Complexity: O(n)
This means the time to create the mapped type grows directly with the number of keys.
[X] Wrong: "Mapping over keys happens instantly no matter how many keys there are."
[OK] Correct: Each key requires a step to create its property, so more keys mean more work.
Understanding how mapped types scale helps you reason about type transformations and their cost in larger codebases.
"What if the mapped type included nested mapped types? How would the time complexity change?"
Practice
Solution
Step 1: Understand mapped types concept
Mapped types create new types by iterating over keys of an existing type, transforming them.Step 2: Differentiate from runtime behavior
Mapped types work at compile time for types, not runtime functions or imports.Final Answer:
Creates a new type by looping over keys of an existing type -> Option DQuick Check:
Mapped type = new type from keys [OK]
- Confusing mapped types with runtime loops
- Thinking mapped types define classes
- Mixing mapped types with imports
Solution
Step 1: Identify mapped type syntax
Mapped types use square brackets with 'in' keyword: {[K in keyof T]: T[K]}Step 2: Check each option
type NewType<T> = { [K in keyof T]: T[K] } matches correct syntax; B uses arrow function incorrectly; C lacks 'in' keyword; D uses string index, not keys of T.Final Answer:
type NewType<T> = { [K in keyof T]: T[K] } -> Option CQuick Check:
Mapped type syntax = {[K in keyof T]: T[K]} [OK]
- Using arrow functions instead of mapped syntax
- Missing 'in' keyword inside brackets
- Using string index instead of keyof T
type Flags = { a: boolean; b: boolean; }, what is the type of type ReadonlyFlags = { readonly [K in keyof Flags]: Flags[K] }?Solution
Step 1: Understand the mapped type with readonly modifier
The mapped type adds 'readonly' before each property key, making all properties readonly.Step 2: Compare with original type
Original Flags has mutable properties; ReadonlyFlags has same keys but readonly modifier added.Final Answer:
{ readonly a: boolean; readonly b: boolean; } -> Option BQuick Check:
Readonly mapped type adds readonly modifier [OK]
- Ignoring readonly modifier effect
- Confusing optional properties with readonly
- Assuming type changes keys or values
type PartialType<T> = { [K of keyof T]?: T[K] }Solution
Step 1: Check mapped type syntax
The correct keyword inside mapped types is 'in', not 'of'.Step 2: Validate other parts
Optional modifier '?' is valid; semicolon is optional; 'keyof T' is correct syntax.Final Answer:
Using 'of' instead of 'in' in the mapped type syntax -> Option AQuick Check:
Mapped types use 'in' keyword [OK]
- Confusing 'in' with 'of' keyword
- Thinking '?' is invalid in mapped types
- Assuming semicolon is mandatory
Solution
Step 1: Combine readonly and optional modifiers correctly
In mapped types, 'readonly' goes before the key, and '?' after the key to make properties optional and readonly.Step 2: Analyze each option
type OptionalReadonly<T> = { readonly [K in keyof T]?: T[K] } correctly places 'readonly' before [K] and '?' after [K]. Options B, C, D misuse placement of modifiers.Final Answer:
type OptionalReadonly<T> = { readonly [K in keyof T]?: T[K] } -> Option AQuick Check:
Readonly + optional = readonly [K in keyof T]? [OK]
- Placing '?' before 'readonly'
- Putting 'readonly' after the key
- Misplacing optional modifier on type instead of key
Ready to prove it?
Pass the test and this pattern moves unknown
