Last Updated: 3/6/2026
P.select Patterns
P.select lets you pick a piece of your input data-structure and injects it in your handler function.
It’s especially useful when pattern matching on deep data structure to avoid the hassle of destructuring it in the handler function.
Selections can be either named (with P.select('someName')) or anonymous (with P.select()).
Anonymous Selection
You can have only one anonymous selection by pattern, and the selected value will be directly inject in your handler as first argument:
import { match, P } from 'ts-pattern';
type Input =
| { type: 'post'; user: { name: string } }
| { ... };
const input: Input = { type: 'post', user: { name: 'Gabriel' } }
const output = match(input)
.with(
{ type: 'post', user: { name: P.select() } },
username => username // username: string
)
.otherwise(() => 'anonymous');
console.log(output);
// => 'Gabriel'Named Selections
If you need to select several things inside your input data structure, you can name your selections by giving a string to P.select(). Each selection will be passed as first argument to your handler in an object.
import { match, P } from 'ts-pattern';
type Input =
| { type: 'post'; user: { name: string }, content: string }
| { ... };
const input: Input = { type: 'post', user: { name: 'Gabriel' }, content: 'Hello!' }
const output = match(input)
.with(
{ type: 'post', user: { name: P.select('name') }, content: P.select('body') },
({ name, body }) => `${name} wrote "${body}"`
)
.otherwise(() => '');
console.log(output);
// => 'Gabriel wrote "Hello!"'Select with Sub-pattern
You can also pass a sub-pattern to P.select if you want it to only select values which match this sub-pattern:
type User = { age: number; name: string };
type Post = { body: string };
type Input = { author: User; content: Post };
declare const input: Input;
const output = match(input)
.with(
{
author: P.select({ age: P.number.gt(18) }),
},
(author) => author // author: User
)
.with(
{
author: P.select('author', { age: P.number.gt(18) }),
content: P.select(),
},
({ author, content }) => author // author: User, content: Post
)
.otherwise(() => 'anonymous');