Skip to Content
Api ReferenceExhaustive And Otherwise

Last Updated: 3/18/2026


.exhaustive() and .otherwise()

These methods execute your pattern matching expression and return the result. They differ in how they handle unmatched cases.

.exhaustive()

Executes the pattern matching expression with compile-time exhaustiveness checking. TypeScript will ensure all possible cases have been handled.

Signature

function exhaustive(): TOutput; function exhaustive(handler: (unexpectedValue: unknown) => TOutput): TOutput;

Basic Usage

type Permission = 'editor' | 'viewer'; type Plan = 'basic' | 'pro'; const fn = (org: Plan, user: Permission) => match([org, user]) .with(['basic', 'viewer'], () => 'basic-viewer') .with(['basic', 'editor'], () => 'basic-editor') .with(['pro', 'viewer'], () => 'pro-viewer') .with(['pro', 'editor'], () => 'pro-editor') .exhaustive(); // ✅ All cases handled!

Missing Case Error

const fn = (org: Plan, user: Permission) => match([org, user]) .with(['basic', 'viewer'], () => {}) .with(['basic', 'editor'], () => {}) .with(['pro', 'viewer'], () => {}) // ❌ TypeScript Error: NonExhaustiveError<['pro', 'editor']> // The ['pro', 'editor'] case isn't handled .exhaustive();

Custom Error Handler

You can provide a custom handler for unexpected values:

match(input) .with(P.string, (str) => str.length) .exhaustive((unexpected) => { console.error(`Unexpected value: ${unexpected}`); return 0; });

.otherwise()

Executes the pattern matching expression with a default handler for unmatched cases. No exhaustiveness checking is performed.

Signature

function otherwise(defaultHandler: (value: TInput) => TOutput): TOutput;

Basic Usage

const output = match(input) .with({ type: 'text' }, (x) => x.content) .with({ type: 'img' }, (x) => x.src) .otherwise(() => 'default value');

Accessing Unmatched Value

The default handler receives the original input value:

const output = match(input) .with({ type: 'text' }, (x) => x.content) .otherwise((unmatchedInput) => { console.log('Unhandled input:', unmatchedInput); return 'fallback'; });

Comparison

Feature.exhaustive().otherwise()
Exhaustiveness checking✅ Yes❌ No
Compilation timeSlightly longerFaster
Default handlerOptionalRequired
Type safetyHigherLower
Use caseWhen you want type safetyWhen you want convenience

When to Use

Use .exhaustive() when:

  • Working with union types where all cases should be handled
  • You want compile-time guarantees that no case is forgotten
  • Building critical logic where missing a case would be a bug

Use .otherwise() when:

  • The input type is very broad (e.g., unknown, any)
  • You intentionally want a catch-all case
  • Exhaustiveness checking is impractical
  • You prefer shorter compilation times

Equivalence

.otherwise(handler) is equivalent to:

.with(P._, handler).exhaustive()