What if your code could think about types and choose the right one all by itself?
Why conditional types are needed in Typescript - The Real Reasons
Imagine you have a function that should return different types based on the input type, and you try to write separate versions for each case manually.
For example, if you pass a string, it returns a number; if you pass a number, it returns a string.
Writing separate functions or many type checks for each input type quickly becomes messy and hard to maintain.
It's easy to make mistakes, and the code grows longer and confusing.
Conditional types let you write one smart type that automatically picks the right output type based on the input type.
This keeps your code clean, safe, and easy to understand.
function process(input: string): number { /*...*/ }
function process(input: number): string { /*...*/ }type Process<T> = T extends string ? number : string;
function process<T>(input: T): Process<T> { /*...*/ }It enables writing flexible, type-safe code that adapts automatically to different input types without repeating yourself.
Think of a function that parses user input: if given a JSON string, it returns an object; if given an object, it returns a JSON string.
Manual type handling is repetitive and error-prone.
Conditional types automate type decisions based on input.
This leads to cleaner, safer, and more maintainable code.
Practice
type Result<T> = T extends number ? string : boolean;Solution
Step 1: Understand conditional types purpose
Conditional types allow choosing one type or another based on a condition, likeT extends number ? string : boolean.Step 2: Match the purpose with options
To select a type based on a condition, making code flexible correctly describes this as selecting a type based on a condition for flexibility.Final Answer:
To select a type based on a condition, making code flexible -> Option DQuick Check:
Conditional types choose types conditionally = D [OK]
- Confusing conditional types with runtime if statements
- Thinking conditional types declare variables
- Believing conditional types create loops
Solution
Step 1: Recall conditional type syntax
The correct syntax usesextendsto check type relations:T extends U ? X : Y.Step 2: Identify correct option
type Check<T> = T extends string ? number : boolean; matches this syntax exactly. Options A, B, and D use invalid syntax for types.Final Answer:
type Check<T> = T extends string ? number : boolean; -> Option AQuick Check:
Conditional type syntax uses extends = C [OK]
- Using runtime if/else syntax in types
- Using == instead of extends
- Omitting the extends keyword
type Check<T> = T extends string ? number : boolean; type Result = Check<'hello'>;
Solution
Step 1: Evaluate the conditional type with T = 'hello'
Since 'hello' is a string,T extends stringis true.Step 2: Determine the resulting type
Because the condition is true, the type becomesnumber.Final Answer:
number -> Option BQuick Check:
'hello' extends string = number [OK]
- Confusing the true and false branches
- Thinking the output is string literal
- Assuming any or unknown type
type Check<T> = T extends number ? 'num' : 'not num'; type Result = Check<>;
Solution
Step 1: Check usage of generic type parameter
The type aliasCheckrequires a type argument, butCheck<>is missing it.Step 2: Confirm other parts are correct
The extends keyword and string literal return types are valid. Declaring a type does not use let or const.Final Answer:
Missing type argument in Check<> -> Option CQuick Check:
Generic types need arguments = B [OK]
- Leaving generic type arguments empty
- Confusing type aliases with variables
- Thinking extends is invalid in types
Flattened?type Flatten<T> = T extends Array ? U : T; type Flattened = Flatten;
Solution
Step 1: Analyze the conditional type with union input
The input isnumber[] | string. Conditional types distribute over unions, so it applies separately tonumber[]andstring.Step 2: Apply Flatten to each part
Fornumber[], it matchesArray<infer U>with U = number, so result is number.
Forstring, it does not match array, so result is string.Step 3: Combine results
The combined result isnumber | string.Final Answer:
number | string -> Option AQuick Check:
Conditional types distribute over unions = A [OK]
- Not distributing over union types
- Returning array instead of element type
- Confusing infer usage
Ready to prove it?
Pass the test and this pattern moves unknown
