Conditional Types
In this page:
Basic Conditional Type
A conditional type checks whether one type extends another using the T extends U ? X : Y syntax, letting a type's shape branch based on a relationship between two other types.
Example: Basic Conditional Type
type IsString<T> = T extends string ? "yes" : "no";
type A = IsString<string>;
type B = IsString<number>;
const a: A = "yes";
console.log(a);
Conditional Types with Generics
Conditional types become especially useful when a generic type parameter determines the result, so the same conditional type definition can produce different concrete output types depending on what's passed in.
Example: Conditional Types with Generics
type Wrapped<T> = T extends string ? string[] : T[];
function wrap<T>(value: T): Wrapped<T> {
return [value] as Wrapped<T>;
}
console.log(wrap("hi"));
Conditional Types with Unions
Conditional types distribute across union members automatically when the checked type is a bare generic type parameter, meaning T extends U ? X : Y effectively runs once per member of a union passed as T.
Example: Conditional Types with Unions
type ToArray<T> = T extends any ? T[] : never;
type Result = ToArray<string | number>;
const r: Result = ["a"];
console.log(r);
infer in Conditional Types
The infer keyword lets a conditional type capture and name part of another type mid-check — for example, extracting the element type out of an array type or the return type out of a function type.
Example: infer in Conditional Types
type ElementType<T> = T extends (infer U)[] ? U : never;
type Item = ElementType<string[]>;
const item: Item = "hello";
console.log(item);
Practical Conditional Types
Conditional types are useful when a reusable type needs to behave differently for different inputs, which is exactly how many of TypeScript's built-in utility types like ReturnType are implemented.
Example: Practical Conditional Types
function greet() {
return "hi";
}
type MyReturnType<T> = T extends (...args: any[]) => infer R ? R : never;
type G = MyReturnType<typeof greet>;
const g: G = "hello";
console.log(g);
Chapter Quiz — Complete all 20 topics to unlock
0/20 topics done
Complete these topics first:
- TypeScript Advanced Types
- Mapped Types
- Conditional Types
- Custom Type Guards
- Assertion Functions
- Control Flow Analysis
- Exhaustiveness Checking
- Satisfies Operator
- Template Literal Types
- Utility Types - Partial
- Utility Types - Required
- Utility Types - Readonly
- Utility Types - Pick
- Utility Types - Omit
- Utility Types - Record
- Utility Types - Exclude and Extract
- Utility Types - NonNullable
- Utility Types - ReturnType
- Utility Types - Parameters
- TypeScript 5 Updates