On this Page
What Are Conditional Types?
Conditional types let you define types based on a condition:
T extends U ? X : Y
If T extends U, the result is type X; otherwise, it is Y.
Basic Syntax
type IsString<t> = T extends string ? "yes" : "no";
type A = IsString<string>; // "yes"
type B = IsString<number>; // "no"
This is great for type-based logic and transformations.
Practical Use Cases
Strip null from a type:
type NonNullable<t> = T extends null | undefined ? never : T;
type A = NonNullable<string null>; // string
Check if type is an array:
type IsArray<t> = T extends any[] ? true : false;
type X = IsArray<string>; // true
type Y = IsArray<number>; // false
Using infer to Extract Types
infer lets you pull out a type from a structure:
type ReturnType<t> = T extends (...args: any[]) => infer R ? R : never;
type Result = ReturnType<() => number>; // number
This is how TypeScript internally builds types like ReturnType, Parameters, ConstructorParameters, etc.
Distributive Conditional Types
Conditional types are distributive over unions by default:
type ToString<t> = T extends number ? string : never;
type X = ToString<1 | 2 | boolean>; // string | never → string
To disable this behavior, wrap the type in a tuple:
type NonDist<t> = [T] extends [number] ? string : boolean;
type A = NonDist<1 | 2>; // boolean (not distributed)
Summary
- Use conditional types to express type-level logic
T extends U ? X : Ygives you conditional output typesinferlets you extract inner types like return values, parameters, etc.- Mastering this unlocks true meta-programming with types
🎉 You’ve now completed the Advanced Guide to TypeScript.
Coming next: Practical Guide to TypeScript – Real-world use cases with React, Node.js, APIs, and more.