100% Free Forever
AI-Powered Learning
Industry Expert Content
Certificates & Badges
Learn At Your Own Pace

TypeScript Conditional Types Cheat Sheet

TypeScript Conditional Types Cheat Sheet

Covers the extends ? : syntax, infer keyword, distributive conditional types, and common utility type patterns built from them.

2 PagesAdvancedApr 5, 2026

Basic Conditional Type Syntax

Conditional types select between two types based on an `extends` check, resolved at compile time.

typescript
type IsString<T> = T extends string ? true : false;type A = IsString<"hi">;   // truetype B = IsString<42>;     // falsetype Flatten<T> = T extends Array<infer Item> ? Item : T;type C = Flatten<string[]>; // stringtype D = Flatten<number>;   // number (falls through)

Extracting Types with `infer`

`infer` introduces a type variable that TypeScript solves for within the conditional branch.

typescript
type ReturnOf<T> = T extends (...args: any[]) => infer R ? R : never;type Fn = () => Promise<string>;type R1 = ReturnOf<Fn>; // Promise<string>type UnwrapPromise<T> = T extends Promise<infer U> ? U : T;type R2 = UnwrapPromise<Promise<number>>; // numbertype FirstArg<T> = T extends (arg: infer A, ...rest: any[]) => any ? A : never;type R3 = FirstArg<(id: string, name: string) => void>; // string

Distributive Conditional Types

Conditional types distribute over naked union types — a key gotcha and a key feature.

typescript
type ToArray<T> = T extends any ? T[] : never;type Result = ToArray<string | number>;// distributes: ToArray<string> | ToArray<number> => string[] | number[]// Wrap in a tuple to disable distribution:type ToArrayNonDist<T> = [T] extends [any] ? T[] : never;type Result2 = ToArrayNonDist<string | number>;// (string | number)[]  — the union stays intact

Built-in Utility Types Using This Pattern

Standard library utilities that are just conditional types under the hood.

typescript
type Exclude<T, U> = T extends U ? never : T;type Extract<T, U> = T extends U ? T : never;type NonNullable<T> = T extends null | undefined ? never : T;type Status = "idle" | "loading" | "error" | "success";type Errored = Extract<Status, "error" | "success">; // "error" | "success"type NotErrored = Exclude<Status, "error">;           // "idle" | "loading" | "success"

Common Conditional Type Patterns

Recipes you'll reuse across codebases.

  • T extends U ? X : Y- core ternary form, evaluated per union member if T is naked
  • infer- captures a subpart of T for use in the true branch
  • [T] extends [U]- wraps in tuple to prevent distribution over unions
  • T extends any ? T : never- forces distribution explicitly
  • Awaited<T>- built-in recursive conditional type that unwraps nested Promises
  • Parameters<T> / ReturnType<T>- infer-based extraction of function signatures
Pro Tip

When a conditional type doesn't distribute the way you expect, check whether T is a 'naked' type parameter — distribution only happens when T appears alone on the left of extends, not wrapped in a tuple, array, or object.

Was this cheat sheet helpful?

Explore Topics

#TypeScriptConditionalTypes#TypeScriptConditionalTypesCheatSheet#Programming#Advanced#BasicConditionalTypeSyntax#ExtractingTypesWithInfer#DistributiveConditionalTypes#Built#CheatSheet#SkillVeris
Advertisement
Sri Hayavadhana Info-Tech

Professional Web Designing Services

  • Responsive Websites
  • E-commerce Solutions
  • SEO Friendly Design
  • Fast & Secure
  • Support & Maintenance
Get a Free Quote

Share this Cheat Sheet