Skip to Content
Overview

Last Updated: 3/6/2026


Patterns Overview

A pattern is a description of the expected shape of your input value.

Patterns can be:

  • Regular JavaScript values ("some string", 10, true, …)
  • Data structures (objects, arrays, …)
  • Wildcards (P._, P.string, P.number, …)
  • Special matcher functions (P.not, P.when, P.select, …)

Importing Patterns

All wildcards and matcher functions can be imported either as Pattern or as P from the ts-pattern module.

import { match, Pattern } from 'ts-pattern'; const toString = (value: unknown): string => match(value) .with(Pattern.string, (str) => str) .with(Pattern.number, (num) => num.toFixed(2)) .with(Pattern.boolean, (bool) => `${bool}`) .otherwise(() => 'Unknown');

Or using the shorter P alias:

import { match, P } from 'ts-pattern'; const toString = (value: unknown): string => match(value) .with(P.string, (str) => str) .with(P.number, (num) => num.toFixed(2)) .with(P.boolean, (bool) => `${bool}`) .otherwise(() => 'Unknown');

Pattern Categories

Literal Patterns

Match exact values:

  • Numbers: 2, 3.14
  • Strings: 'hello', 'world'
  • Booleans: true, false
  • Special values: null, undefined, NaN
  • BigInts: 20n
  • Symbols

Wildcard Patterns

Match any value of a specific type:

  • P._ or P.any - matches anything
  • P.string - matches any string
  • P.number - matches any number
  • P.boolean - matches any boolean
  • P.bigint - matches any bigint
  • P.symbol - matches any symbol
  • P.nullish - matches null or undefined
  • P.nonNullable - matches anything except null or undefined

Data Structure Patterns

Match complex data structures:

  • Objects: { key: pattern, ... }
  • Arrays/Tuples: [pattern1, pattern2, ...]
  • Arrays (variable length): P.array(pattern)
  • Records: P.record(keyPattern, valuePattern)
  • Sets: P.set(pattern)
  • Maps: P.map(keyPattern, valuePattern)

Matcher Function Patterns

Advanced pattern matching:

  • P.when(predicate) - custom predicate functions
  • P.not(pattern) - inverse of a pattern
  • P.select(name?) - extract and inject values
  • P.optional(pattern) - optional properties
  • P.instanceOf(Class) - class instance checking
  • P.union(...patterns) - match any of several patterns
  • P.intersection(...patterns) - match all of several patterns

Type-Specific Predicates

Refined matching for specific types:

  • String predicates: P.string.startsWith(), P.string.endsWith(), P.string.includes(), etc.
  • Number predicates: P.number.gt(), P.number.lt(), P.number.between(), etc.
  • BigInt predicates: P.bigint.gt(), P.bigint.lt(), P.bigint.between(), etc.

Type Inference

If your input isn’t typed (if it’s any or unknown), you are free to use any possible pattern. Your handler will infer the input type from the shape of your pattern.

const input: unknown = { type: 'user', name: 'Alice' }; match(input) .with({ type: 'user', name: P.string }, (user) => { // user is inferred as { type: 'user', name: string } console.log(user.name); }) .otherwise(() => {});

Next Steps

Explore specific pattern types: