Skip to Content
Api ReferenceIsmatching Function

Last Updated: 3/18/2026


isMatching() Function

isMatching is a type guard function that checks if a value matches a given pattern. It’s useful for runtime validation and type narrowing outside of match expressions.

Signatures

Curried Form (Returns Type Guard)

function isMatching<P extends Pattern<any>>( pattern: P ): (value: any) => value is InvertPattern<P>;

Direct Form (Returns Boolean)

function isMatching<P extends Pattern<any>>( pattern: P, value: any ): value is InvertPattern<P>;

Usage

Single Argument (Curried)

Creates a reusable type guard function:

import { isMatching, P } from 'ts-pattern'; const isBlogPost = isMatching({ type: 'blogpost', title: P.string, description: P.string, }); if (isBlogPost(value)) { // ✅ value: { type: 'blogpost', title: string, description: string } console.log(value.title); }

Two Arguments (Direct)

Direct boolean check:

const blogPostPattern = { type: 'blogpost', title: P.string, description: P.string, } as const; if (isMatching(blogPostPattern, value)) { // ✅ value is narrowed to match the pattern console.log(value.title); }

Examples

API Response Validation

const userPattern = { id: P.number, name: P.string, email: P.string, age: P.number.optional(), } as const; async function fetchUser(id: number) { const response = await fetch(`/api/users/${id}`); const data: unknown = await response.json(); if (isMatching(userPattern, data)) { // ✅ data is now typed as User return data; } throw new Error('Invalid user data'); }

Array Filtering

const isValidPost = isMatching({ title: P.string.minLength(1), content: P.string.minLength(10), author: { name: P.string }, }); const posts: unknown[] = await fetchPosts(); // Filter and narrow type in one go const validPosts = posts.filter(isValidPost); // validPosts: Array<{ title: string, content: string, author: { name: string } }>

Complex Validation

const isAdultUser = isMatching({ type: 'user', age: P.number.gte(18), verified: true, }); function processUser(input: unknown) { if (isAdultUser(input)) { // input is narrowed to verified adult user console.log(`Processing user: ${input.age} years old`); } }

Union Type Narrowing

type Response = | { status: 'success'; data: string } | { status: 'error'; error: Error } | { status: 'loading' }; const isSuccess = isMatching({ status: 'success' }); const isError = isMatching({ status: 'error' }); function handleResponse(response: Response) { if (isSuccess(response)) { // response: { status: 'success'; data: string } return response.data; } if (isError(response)) { // response: { status: 'error'; error: Error } throw response.error; } // response: { status: 'loading' } return 'Loading...'; }

Type Inference

The as const assertion helps TypeScript infer the most precise types:

// Without 'as const' const pattern1 = { type: 'user', role: P.string }; // Inferred as: { type: string, role: Pattern<string> } // With 'as const' const pattern2 = { type: 'user', role: P.string } as const; // Inferred as: { type: 'user', role: Pattern<string> }

Benefits

  • Type-safe validation: Combines runtime checks with compile-time type narrowing
  • Reusable: Create validators once, use them anywhere
  • Composable: Use with array methods like .filter(), .find(), .some()
  • Readable: Pattern syntax is more declarative than manual type guards