Bird
Raised Fist0
Typescriptprogramming~20 mins

Distributive conditional types in Typescript - Practice Problems & Coding Challenges

Choose your learning style10 modes available
Challenge - 5 Problems
🎖️
Distributive Conditional Types Master
Get all challenges correct to earn this badge!
Test your skills under time pressure!
❓ Predict Output
intermediate
2:00remaining
Output of a simple distributive conditional type
What is the type of Result after the following code runs?
Typescript
type A = "x" | "y" | "z";
type Result = A extends "x" ? 1 : 0;
A1 | 0
B0
C1
D"1" | 0
Attempts:
2 left
💡 Hint
Remember that conditional types distribute over unions by default.
🧠 Conceptual
intermediate
2:00remaining
Understanding distribution with 'never'
What is the resulting type of Filtered in this code?
Typescript
type Filter<T> = T extends string ? T : never;
type Filtered = Filter<number | string | boolean>;
Astring
Bnumber | string | boolean
Cnever
Dstring | never
Attempts:
2 left
💡 Hint
Conditional types remove members that don't satisfy the condition by turning them into 'never'.
🔧 Debug
advanced
2:00remaining
Why does this distributive conditional type not behave as expected?
Consider this code snippet. What is the type of Result and why might it be unexpected?
Typescript
type Wrap<T> = (arg: T) => void;
type Result = Wrap<string> | Wrap<number> extends (arg: infer U) => void ? U : never;
Astring
Bstring & number
Cnumber
Dstring | number
Attempts:
2 left
💡 Hint
Conditional types distribute only when the checked type is a naked type parameter.
📝 Syntax
advanced
2:00remaining
Which option correctly uses distributive conditional types to extract types?
Which of the following type definitions correctly extracts only the string types from a union?
Atype ExtractString<T> = T extends string & number ? T : never;
Btype ExtractString<T> = T extends (string | number) ? string : never;
Ctype ExtractString<T> = T extends string | never ? T : never;
Dtype ExtractString<T> = T extends string ? T : never;
Attempts:
2 left
💡 Hint
Distributive conditional types work when the checked type is a naked type parameter.
🚀 Application
expert
2:00remaining
Calculate the number of keys in a mapped distributive conditional type
Given the following code, how many keys does the type Result have?
Typescript
type Keys<T> = T extends any ? keyof T : never;
type Union = { a: number } | { b: string };
type Result = Keys<Union>;
A3
B1
C2
D0
Attempts:
2 left
💡 Hint
Remember that conditional types distribute over unions and 'keyof' returns keys of each member.

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