Skip to Content
Literals

Last Updated: 3/6/2026


Literal Patterns

Literals are primitive JavaScript values that can be used directly as patterns.

Supported Literals

Numbers

import { match } from 'ts-pattern'; const result = match(input) .with(0, () => 'zero') .with(1, () => 'one') .with(42, () => 'the answer') .with(3.14, () => 'pi') .otherwise(() => 'other number');

Strings

const result = match(input) .with('hello', () => 'greeting') .with('goodbye', () => 'farewell') .with('', () => 'empty string') .otherwise(() => 'other string');

Booleans

const result = match(input) .with(true, () => 'truthy') .with(false, () => 'falsy') .exhaustive();

null and undefined

const result = match(input) .with(null, () => 'null value') .with(undefined, () => 'undefined value') .otherwise(() => 'has a value');

NaN

const result = match(input) .with(NaN, () => 'not a number') .with(P.number, (n) => `number: ${n}`) .otherwise(() => 'other');

BigInt

const result = match(input) .with(0n, () => 'zero bigint') .with(20n, () => 'twenty bigint') .with(P.bigint, (n) => `bigint: ${n}`) .otherwise(() => 'not a bigint');

Symbols

const MY_SYMBOL = Symbol('my-symbol'); const result = match(input) .with(MY_SYMBOL, () => 'found my symbol') .with(P.symbol, () => 'some other symbol') .otherwise(() => 'not a symbol');

Complete Example

import { match, P } from 'ts-pattern'; const input: unknown = 2; const output = match(input) .with(2, () => 'number: two') .with(true, () => 'boolean: true') .with('hello', () => 'string: hello') .with(undefined, () => 'undefined') .with(null, () => 'null') .with(NaN, () => 'number: NaN') .with(20n, () => 'bigint: 20n') .otherwise(() => 'something else'); console.log(output); // => 'number: two'

Type Narrowing

When using literal patterns with union types, TypeScript will automatically narrow the type:

type Status = 'idle' | 'loading' | 'success' | 'error'; const getStatusMessage = (status: Status) => match(status) .with('idle', (s) => { // s is narrowed to 'idle' return 'Ready to start'; }) .with('loading', (s) => { // s is narrowed to 'loading' return 'Please wait...'; }) .with('success', 'error', (s) => { // s is narrowed to 'success' | 'error' return s === 'success' ? 'Done!' : 'Failed!'; }) .exhaustive();

Best Practices

  1. Use literals for exact matches: When you know the exact value you’re matching
  2. Combine with wildcards: Use literals for specific cases, wildcards for general ones
  3. Leverage type narrowing: Let TypeScript infer precise types from your patterns
  4. Group related literals: Use multiple patterns in a single .with() for similar cases
// Good: Grouped related cases match(httpStatus) .with(200, 201, 204, () => 'Success') .with(400, 401, 403, 404, () => 'Client Error') .with(500, 502, 503, () => 'Server Error') .otherwise(() => 'Unknown Status');