> For the complete documentation index, see [llms.txt](https://rajdee.gitbook.io/redux-toolkit-in-russian/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://rajdee.gitbook.io/redux-toolkit-in-russian/soderzhanie/spravochnik-po-api/prochee/matching-utilities.md).

# Matching Utilities

Redux Toolkit exports several type-safe action matching utilities that you can leverage when checking for specific kinds of actions. These are primarily useful for the `builder.addMatcher()` cases in `createSlice` and `createReducer`, as well as when writing custom middleware.

#### General Purpose

* `isAllOf` - returns true when **all** conditions are met
* `isAnyOf` - returns true when **at least one of** the conditions are met

#### `createAsyncThunk`-specific matchers

All these matchers can either be called with one or more thunks as arguments, in which case they will return a matcher function for that condition and thunks, or with one actions, in which case they will match for any thunk action with said condition.

* `isAsyncThunkAction` - accepts one or more action creators and returns true when all match
* `isPending` - accepts one or more action creators and returns true when all match
* `isFulfilled` - accepts one or more action creators and returns true when all match
* `isRejected` - accepts one or more action creators and returns true when all match
* `isRejectedWithValue` - accepts one or more action creators and returns true when all match

### `isAllOf`

A higher-order function that accepts one or more of:

* `redux-toolkit` action creator functions such as the ones produced by:
  * [`createAction`](https://app.gitbook.com/s/-MQr6miY_tsYohlEf531/soderzhanie/spravochnik-po-api/prochee/createAction)
  * [`createSlice`](https://app.gitbook.com/s/-MQr6miY_tsYohlEf531/soderzhanie/spravochnik-po-api/prochee/createSlice#return-value)
  * [`createAsyncThunk`](https://app.gitbook.com/s/-MQr6miY_tsYohlEf531/soderzhanie/spravochnik-po-api/prochee/createAsyncThunk#promise-lifecycle-actions)
* type guard functions
* custom action creator functions that have a `.match` property that is a type guard

It will return a type guard function that returns `true` if *all* of the provided functions match.

### `isAnyOf`

Accepts the same inputs as `isAllOf` and will return a type guard function that returns `true` if at least one of the provided functions match.

### `isAsyncThunkAction`

A higher-order function that returns a type guard function that may be used to check whether an action was created by [`createAsyncThunk`](https://app.gitbook.com/s/-MQr6miY_tsYohlEf531/soderzhanie/spravochnik-po-api/prochee/createAsyncThunk).

\`\`\`ts title="isAsyncThunkAction usage" import { isAsyncThunkAction, AnyAction } from '@reduxjs/toolkit' import { requestThunk1, requestThunk2 } from '@virtual/matchers'

const isARequestAction = isAsyncThunkAction(requestThunk1, requestThunk2)

function handleRequestAction(action: AnyAction) { if (isARequestAction(action)) { // action is an action dispatched by either `requestThunk1` or `requestThunk2` } }

````
## `isPending`

A higher-order function that returns a type guard function that may be used to check whether an action is a 'pending' action creator from the `createAsyncThunk` promise lifecycle.

```ts title="isPending usage"
import { isPending, AnyAction } from '@reduxjs/toolkit'
import { requestThunk1, requestThunk2 } from '@virtual/matchers'

const isAPendingAction = isPending(requestThunk1, requestThunk2)

function handlePendingAction(action: AnyAction) {
  if (isAPendingAction(action)) {
    // action is a pending action dispatched by either `requestThunk1` or `requestThunk2`
  }
}
````

### `isFulfilled`

A higher-order function that returns a type guard function that may be used to check whether an action is a 'fulfilled'' action creator from the `createAsyncThunk` promise lifecycle.

\`\`\`ts title="isFulfilled usage" import { isFulfilled, AnyAction } from '@reduxjs/toolkit' import { requestThunk1, requestThunk2 } from '@virtual/matchers'

const isAFulfilledAction = isFulfilled(requestThunk1, requestThunk2)

function handleFulfilledAction(action: AnyAction) { if (isAFulfilledAction(action)) { // action is a fulfilled action dispatched by either `requestThunk1` or `requestThunk2` } }

````
## `isRejected`

A higher-order function that returns a type guard function that may be used to check whether an action is a 'rejected' action creator from the `createAsyncThunk` promise lifecycle.

```ts title="isRejected usage"
import { isRejected, AnyAction } from '@reduxjs/toolkit'
import { requestThunk1, requestThunk2 } from '@virtual/matchers'

const isARejectedAction = isRejected(requestThunk1, requestThunk2)

function handleRejectedAction(action: AnyAction) {
  if (isARejectedAction(action)) {
    // action is a rejected action dispatched by either `requestThunk1` or `requestThunk2`
  }
}
````

### `isRejectedWithValue`

A higher-order function that returns a type guard function that may be used to check whether an action is a 'rejected' action creator from the `createAsyncThunk` promise lifecycle that was created by [`rejectWithValue`](https://app.gitbook.com/s/-MQr6miY_tsYohlEf531/soderzhanie/spravochnik-po-api/prochee/createAsyncThunk#handling-thunk-errors).

\`\`\`ts title="isRejectedWithValue usage" import { isRejectedWithValue, AnyAction } from '@reduxjs/toolkit' import { requestThunk1, requestThunk2 } from '@virtual/matchers'

const isARejectedWithValueAction = isRejectedWithValue( requestThunk1, requestThunk2 )

function handleRejectedWithValueAction(action: AnyAction) { if (isARejectedWithValueAction(action)) { // action is a rejected action dispatched by either `requestThunk1` or `requestThunk2` // where rejectWithValue was used } }

````
## Using matchers to reduce code complexity, duplication and boilerplate

When using the `builder` pattern to construct a reducer, we add cases or matchers one at a time. However, by using `isAnyOf` or `isAllOf`,
we're able to easily use the same matcher for several cases in a type-safe manner.

First, let's examine an unnecessarily complex example:

```ts title="Example without using a matcher utility"
import {
  createAsyncThunk,
  createReducer,
  PayloadAction
} from '@reduxjs/toolkit'

interface Data {
  isInteresting: boolean
  isSpecial: boolean
}

interface Special extends Data {
  isSpecial: true
}

interface Interesting extends Data {
  isInteresting: true
}

function isSpecial(
  action: PayloadAction<Data>
): action is PayloadAction<Special> {
  return action.payload.isSpecial
}

function isInteresting(
  action: PayloadAction<Data>
): action is PayloadAction<Interesting> {
  return action.payload.isInteresting
}

interface ExampleState {
  isSpecial: boolean
  isInteresting: boolean
}

const initialState: ExampleState = {
  isSpecial: false,
  isInteresting: false
}

export const isSpecialAndInterestingThunk = createAsyncThunk(
  'isSpecialAndInterestingThunk',
  () => {
    return {
      isSpecial: true,
      isInteresting: true
    }
  }
)

// This has unnecessary complexity
const loadingReducer = createReducer(initialState, builder => {
  builder.addCase(isSpecialAndInterestingThunk.fulfilled, (state, action) => {
    if (isSpecial(action)) {
      state.isSpecial = true
    }
    if (isInteresting(action)) {
      state.isInteresting = true
    }
  })
})
````

In this scenario, we can use `isAllOf` to simplify our code and reduce some of the boilerplate.

\`\`\`ts title="Refactoring with isAllOf" import { createReducer, isAllOf } from '@reduxjs/toolkit' import { isSpecialAndInterestingThunk, initialState, isSpecial, isInteresting, Data } from '@virtual/matchers' // This is a fake pkg that provides the types shown above

const loadingReducer = createReducer(initialState, builder => { builder .addMatcher( isAllOf(isSpecialAndInterestingThunk.fulfilled, isSpecial), (state, action) => { state.isSpecial = true } ) .addMatcher( isAllOf(isSpecialAndInterestingThunk.fulfilled, isInteresting), (state, action) => { state.isInteresting = true } ) })

````
## Using matchers as a TypeScript Type Guard

The function returned by `isAllOf` and `isAnyOf` can also be used as a TypeScript type guard in other contexts.

```ts title="Using isAllOf as a type guard"
import { isAllOf, PayloadAction } from '@reduxjs/toolkit'
import { Data, isSpecial, isInteresting } from '@virtual/matchers' // This is a fake pkg that provides the types shown above

const isSpecialAndInteresting = isAllOf(isSpecial, isInteresting)

function someFunction(action: PayloadAction<Data>) {
  if (isSpecialAndInteresting(action)) {
    // "action" will be correctly typed as:
    // `PayloadAction<Special> & PayloadAction<Interesting>`
  }
}
````

\`\`\`ts title="Using isAnyOf as a type guard" import { isAnyOf, PayloadAction } from '@reduxjs/toolkit' import { Data, isSpecial, isInteresting } from '@virtual/matchers' // this is a fake pkg that provides the types shown above

const isSpecialOrInteresting = isAnyOf(isSpecial, isInteresting)

function someFunction(action: PayloadAction) { if (isSpecialOrInteresting(action)) { // "action" will be correctly typed as: // `PayloadAction<Special> | PayloadAction<Interesting>` } }

\`\`\`

### Example

\<iframe src="<https://codesandbox.io/embed/redux-toolkit-matchers-example-e765q?fontsize=14&hidenavigation=1&module=%2Fsrc%2Ffeatures%2Fcounter%2FcounterSlice.ts&theme=dark>" style= title="redux-toolkit-matchers-example" allow="accelerometer; ambient-light-sensor; camera; encrypted-media; geolocation; gyroscope; hid; microphone; midi; payment; usb; vr; xr-spatial-tracking" sandbox="allow-forms allow-modals allow-popups allow-presentation allow-same-origin allow-scripts"

> \</iframe>


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://rajdee.gitbook.io/redux-toolkit-in-russian/soderzhanie/spravochnik-po-api/prochee/matching-utilities.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
