Bird
Raised Fist0
Typescriptprogramming~5 mins

Distributive conditional types in Typescript - Time & Space Complexity

Choose your learning style10 modes available
Time Complexity: Distributive conditional types
O(n)
Understanding Time Complexity

We want to understand how the time it takes to evaluate distributive conditional types changes as the input type grows.

Specifically, how does TypeScript handle conditional checks on union types?

Scenario Under Consideration

Analyze the time complexity of the following TypeScript distributive conditional type.


type FilterString = T extends string ? T : never;

// Example usage:
type Result = FilterString<'a' | 1 | 'b' | boolean>;

This type checks each member of a union and keeps only the string members.

Identify Repeating Operations

Look for repeated checks or operations in the type evaluation.

  • Primary operation: Conditional check on each union member.
  • How many times: Once per member in the union type.
How Execution Grows With Input

Each union member is checked separately, so the work grows as the number of members grows.

Input Size (n)Approx. Operations
33 conditional checks
1010 conditional checks
100100 conditional checks

Pattern observation: The number of checks grows directly with the number of union members.

Final Time Complexity

Time Complexity: O(n)

This means the time to evaluate grows linearly with the number of union members.

Common Mistake

[X] Wrong: "The conditional type runs once for the whole union at once."

[OK] Correct: TypeScript actually distributes the conditional over each union member separately, so it runs multiple times.

Interview Connect

Understanding how TypeScript processes distributive conditional types helps you reason about type performance and complexity in real projects.

Self-Check

"What if we changed the conditional type to not distribute over unions? How would the time complexity change?"

Practice

(1/5)
1. What does a distributive conditional type do in TypeScript?
T extends U ? X : Y when T is a union type?
easy
A. Applies the condition separately to each member of the union type
B. Applies the condition once to the entire union type as a whole
C. Always returns the true branch X regardless of T
D. Always returns the false branch Y regardless of T

Solution

  1. Step 1: Understand conditional types with unions

    When T is a union, TypeScript distributes the condition over each member separately.
  2. Step 2: Apply distributive behavior

    Each member of T is checked against U individually, returning X or Y per member.
  3. Final Answer:

    Applies the condition separately to each member of the union type -> Option A
  4. Quick Check:

    Distributive conditional types = separate checks per union member [OK]
Hint: Remember: conditional types split unions into parts [OK]
Common Mistakes:
  • Thinking the condition applies once to the whole union
  • Assuming it always returns true or false branch
  • Confusing distributive with non-distributive conditional types
2. Which of the following is the correct syntax for a distributive conditional type in TypeScript?
easy
A. type Result<T> = if (T extends string) number else boolean;
B. type Result<T> = T => string ? number : boolean;
C. type Result<T> = T ? number : boolean;
D. type Result<T> = T extends string ? number : boolean;

Solution

  1. Step 1: Recall correct conditional type syntax

    Conditional types use T extends U ? X : Y syntax in TypeScript.
  2. Step 2: Match syntax with options

    type Result<T> = T extends string ? number : boolean; matches the correct syntax; others use invalid or incorrect syntax.
  3. Final Answer:

    type Result<T> = T extends string ? number : boolean; -> Option D
  4. Quick Check:

    Conditional types use extends ? : syntax [OK]
Hint: Look for extends ? : pattern in type definitions [OK]
Common Mistakes:
  • Using if-else instead of conditional operator
  • Missing the extends keyword
  • Using arrow functions incorrectly in type definitions
3. Given the type:
type FilterString<T> = T extends string ? T : never;
type Result = FilterString<'a' | 1 | 'b' | true>;

What is the type of Result?
medium
A. never
B. 'a' | 1 | 'b' | true
C. 'a' | 'b'
D. string

Solution

  1. Step 1: Apply distributive conditional type to each union member

    Each member is checked: 'a' extends string (true), 1 extends string (false), 'b' extends string (true), true extends string (false).
  2. Step 2: Collect true branch results

    Only 'a' and 'b' remain; others become never and are removed from union.
  3. Final Answer:

    'a' | 'b' -> Option C
  4. Quick Check:

    FilterString filters strings only = 'a' | 'b' [OK]
Hint: Distributive types filter unions by returning never for false cases [OK]
Common Mistakes:
  • Thinking the whole union is returned unchanged
  • Confusing never with empty string
  • Assuming the result is just string instead of filtered literals
4. Identify the error in this distributive conditional type:
type ExtractNumber<T> = [T] extends [number] ? T : never;
type Result = ExtractNumber<'a' | 1 | 2>;
medium
A. The condition is wrapped in a tuple, so distribution does not occur
B. The syntax is invalid because of missing extends keyword
C. The type will always return never
D. The union type is not allowed in conditional types

Solution

  1. Step 1: Understand tuple wrapping effect

    Wrapping T in a tuple disables distributive behavior in conditional types.
  2. Step 2: Analyze impact on ExtractNumber

    Since distribution is off, the whole union is checked at once, so 'a' | 1 | 2 extends number is false, returning never.
  3. Final Answer:

    The condition is wrapped in a tuple, so distribution does not occur -> Option A
  4. Quick Check:

    Tuple wrapping disables distributive conditional types [OK]
Hint: Tuple brackets stop distribution in conditional types [OK]
Common Mistakes:
  • Assuming distribution still happens with tuple wrapping
  • Confusing syntax error with logic error
  • Thinking union types are not allowed in conditional types
5. How can you create a type that converts a union of types T into a union of their array types using distributive conditional types?
Choose the correct type definition.
hard
A. type ToArray<T> = T extends any[] ? T : never;
B. type ToArray<T> = T extends any ? T[] : never;
C. type ToArray<T> = T[];
D. type ToArray<T> = [T] extends [any] ? T[] : never;

Solution

  1. Step 1: Understand distributive conditional type for mapping

    Using T extends any ? T[] : never applies the array transformation to each union member separately.
  2. Step 2: Compare options

    type ToArray<T> = T extends any ? T[] : never; correctly distributes and converts each member to an array type. type ToArray<T> = [T] extends [any] ? T[] : never; disables distribution by tuple wrapping. type ToArray<T> = T[]; wraps the whole union as an array, not each member. type ToArray<T> = T extends any[] ? T : never; filters arrays, not converts.
  3. Final Answer:

    type ToArray<T> = T extends any ? T[] : never; -> Option B
  4. Quick Check:

    Distributive conditional types map unions member-wise [OK]
Hint: Use T extends any ? to distribute over unions [OK]
Common Mistakes:
  • Wrapping T in tuple disables distribution
  • Using T[] directly converts whole union, not members
  • Confusing filtering with mapping in conditional types
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard