Conditional type syntax in Typescript - Time & Space Complexity
We want to understand how the time it takes to evaluate a conditional type changes as the input type changes.
How does the complexity grow when TypeScript checks conditions on types?
Analyze the time complexity of the following TypeScript conditional type.
type IsString<T> = T extends string ? true : false;
// Usage example:
type Test1 = IsString<string>; // true
type Test2 = IsString<number>; // false
This code checks if a type T is a string type and returns true or false accordingly.
Look for repeated checks or evaluations in the conditional type.
- Primary operation: TypeScript checks if T extends string.
- How many times: Once per type evaluation; no loops or recursion here.
The check is simple and happens once per type. Even if T is complex, this conditional runs a single check.
| Input Size (n) | Approx. Operations |
|---|---|
| 1 (simple type) | 1 check |
| 10 (union of 10 types) | 10 checks (one per union member) |
| 100 (union of 100 types) | 100 checks |
Pattern observation: The number of checks grows linearly with the number of union members in the input type.
Time Complexity: O(n)
This means the time to evaluate grows in a straight line as the number of types to check increases.
[X] Wrong: "Conditional types always run instantly regardless of input size."
[OK] Correct: When the input is a union type, TypeScript evaluates the condition for each member, so time grows with the number of members.
Understanding how conditional types scale helps you write efficient type logic and shows you think about performance even in type-level code.
"What if we changed the conditional type to check nested conditional types? How would the time complexity change?"
Practice
T extends U ? X : YSolution
Step 1: Understand the conditional type syntax
The syntaxT extends U ? X : Ymeans if type T can be assigned to type U, then use type X.Step 2: Interpret the meaning
If T is not assignable to U, then the type becomes Y instead.Final Answer:
Chooses type X if T is assignable to U, otherwise type Y -> Option BQuick Check:
Conditional type picks between X and Y based on T extends U [OK]
- Thinking it returns a boolean value
- Confusing extends with equality check
- Assuming it creates a function
Solution
Step 1: Recall the correct conditional type syntax
TypeScript usestype Result = T extends U ? X : Y;to define conditional types.Step 2: Identify incorrect options
Options A, B, and C use invalid syntax not supported by TypeScript.Final Answer:
type Result = T extends U ? X : Y; -> Option CQuick Check:
Correct conditional type syntax uses ? and : [OK]
- Using if-else keywords inside type definitions
- Misplacing question mark or colon
- Writing 'then' instead of '?'
type Check<T> = T extends string ? number : boolean;
type Result = Check<'hello'>;
Solution
Step 1: Analyze the conditional type Check<T>
If T extends string, then the type is number; otherwise boolean.Step 2: Substitute T with 'hello'
'hello' is a string literal, so it extends string, making the type number.Final Answer:
number -> Option AQuick Check:
'hello' extends string -> number [OK]
- Confusing the output type with input type
- Assuming literal types don't extend their base types
- Choosing boolean instead of number
type Example<T> = T extends number ? 'num' : 'not num'
Solution
Step 1: Review the conditional type syntax
The syntaxtype Example<T> = T extends number ? 'num' : 'not num'is valid in TypeScript.Step 2: Check for syntax errors
Semicolon after type alias is optional; string literals are valid return types.Final Answer:
No error, syntax is correct -> Option DQuick Check:
Conditional types can return string literals [OK]
- Expecting semicolon is mandatory
- Thinking extends is only for classes
- Believing string literals can't be types
type Flatten<T> = T extends any[] ? T[number] : T;
What is the type of
Flatten<string[] | number>?Solution
Step 1: Understand the conditional type Flatten<T>
If T is an array type, it returns the element type (T[number]), else returns T itself.Step 2: Apply Flatten to union type string[] | number
Conditional types distribute over unions, so Flatten<string[] | number> = Flatten<string[]> | Flatten<number> = string | number.Final Answer:
string | number -> Option AQuick Check:
Conditional types distribute over unions [OK]
- Not distributing over union types
- Returning array type instead of element type
- Confusing T[number] with T
Ready to prove it?
Pass the test and this pattern moves unknown
