codez.guru

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[]) =&gt; infer R ? R : never;

type Result = ReturnType&lt;() =&gt; number&gt;; // 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&lt;1 | 2 | boolean&gt;; // string | never → string

To disable this behavior, wrap the type in a tuple:

type NonDist<t> = [T] extends [number] ? string : boolean;

type A = NonDist&lt;1 | 2&gt;; // boolean (not distributed)

Summary

  • Use conditional types to express type-level logic
  • T extends U ? X : Y gives you conditional output types
  • infer lets 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.