Skip to content

Prefer UnknownAction and Action to AnyAction #3363

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 20 commits into from
May 30, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions docs/api/configureStore.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ to the store setup for a better development experience.

interface ConfigureStoreOptions<
S = any,
A extends Action = AnyAction,
A extends Action = UnknownAction,
M extends Middlewares<S> = Middlewares<S>
E extends Enhancers = Enhancers
> {
Expand Down Expand Up @@ -64,7 +64,7 @@ interface ConfigureStoreOptions<
enhancers?: (getDefaultEnhancers: GetDefaultEnhancers<M>) => E | E
}

function configureStore<S = any, A extends Action = AnyAction>(
function configureStore<S = any, A extends Action = UnknownAction>(
options: ConfigureStoreOptions<S, A>
): EnhancedStore<S, A>
```
Expand Down
4 changes: 2 additions & 2 deletions docs/api/createDynamicMiddleware.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ The "dynamic middleware instance" returned from `createDynamicMiddleware` is an
```ts no-transpile
export type DynamicMiddlewareInstance<
State = unknown,
Dispatch extends ReduxDispatch<AnyAction> = ReduxDispatch<AnyAction>
Dispatch extends ReduxDispatch<UnknownAction> = ReduxDispatch<UnknownAction>
> = {
middleware: DynamicMiddleware<State, Dispatch>
addMiddleware: AddMiddleware<State, Dispatch>
Expand Down Expand Up @@ -131,7 +131,7 @@ _These depend on having `react-redux` installed._
```ts no-transpile
interface ReactDynamicMiddlewareInstance<
State = any,
Dispatch extends ReduxDispatch<AnyAction> = ReduxDispatch<AnyAction>
Dispatch extends ReduxDispatch<UnknownAction> = ReduxDispatch<UnknownAction>
> extends DynamicMiddlewareInstance<State, Dispatch> {
createDispatchWithMiddlewareHook: CreateDispatchWithMiddlewareHook<
State,
Expand Down
12 changes: 6 additions & 6 deletions docs/api/createListenerMiddleware.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -120,10 +120,10 @@ The "listener middleware instance" returned from `createListenerMiddleware` is a
```ts no-transpile
interface ListenerMiddlewareInstance<
State = unknown,
Dispatch extends ThunkDispatch<State, unknown, AnyAction> = ThunkDispatch<
Dispatch extends ThunkDispatch<State, unknown, UnknownAction> = ThunkDispatch<
State,
unknown,
AnyAction
UnknownAction
>,
ExtraArgument = unknown
> {
Expand Down Expand Up @@ -181,7 +181,7 @@ interface AddListenerOptions {
effect: (action: Action, listenerApi: ListenerApi) => void | Promise<void>
}

type ListenerPredicate<Action extends AnyAction, State> = (
type ListenerPredicate<Action extends ReduxAction, State> = (
action: Action,
currentState?: State,
originalState?: State
Expand Down Expand Up @@ -321,7 +321,7 @@ The `listenerApi` object is the second argument to each listener callback. It co
```ts no-transpile
export interface ListenerEffectAPI<
State,
Dispatch extends ReduxDispatch<AnyAction>,
Dispatch extends ReduxDispatch<UnknownAction>,
ExtraArgument = unknown
> extends MiddlewareAPI<Dispatch, State> {
// NOTE: MiddlewareAPI contains `dispatch` and `getState` already
Expand Down Expand Up @@ -572,12 +572,12 @@ Listeners can use the `condition` and `take` methods in `listenerApi` to wait un
The signatures are:

```ts no-transpile
type ConditionFunction<Action extends AnyAction, State> = (
type ConditionFunction<Action extends ReduxAction, State> = (
predicate: ListenerPredicate<Action, State> | (() => boolean),
timeout?: number
) => Promise<boolean>

type TakeFunction<Action extends AnyAction, State> = (
type TakeFunction<Action extends ReduxAction, State> = (
predicate: ListenerPredicate<Action, State> | (() => boolean),
timeout?: number
) => Promise<[Action, State, State] | null>
Expand Down
25 changes: 11 additions & 14 deletions docs/api/matching-utilities.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -49,12 +49,12 @@ A higher-order function that returns a type guard function that may be used to c

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

const isARequestAction = isAsyncThunkAction(requestThunk1, requestThunk2)

function handleRequestAction(action: AnyAction) {
function handleRequestAction(action: UnknownAction) {
if (isARequestAction(action)) {
// action is an action dispatched by either `requestThunk1` or `requestThunk2`
}
Expand All @@ -67,12 +67,12 @@ A higher-order function that returns a type guard function that may be used to c

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

const isAPendingAction = isPending(requestThunk1, requestThunk2)

function handlePendingAction(action: AnyAction) {
function handlePendingAction(action: UnknownAction) {
if (isAPendingAction(action)) {
// action is a pending action dispatched by either `requestThunk1` or `requestThunk2`
}
Expand All @@ -85,12 +85,12 @@ A higher-order function that returns a type guard function that may be used to c

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

const isAFulfilledAction = isFulfilled(requestThunk1, requestThunk2)

function handleFulfilledAction(action: AnyAction) {
function handleFulfilledAction(action: UnknownAction) {
if (isAFulfilledAction(action)) {
// action is a fulfilled action dispatched by either `requestThunk1` or `requestThunk2`
}
Expand All @@ -103,12 +103,12 @@ A higher-order function that returns a type guard function that may be used to c

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

const isARejectedAction = isRejected(requestThunk1, requestThunk2)

function handleRejectedAction(action: AnyAction) {
function handleRejectedAction(action: UnknownAction) {
if (isARejectedAction(action)) {
// action is a rejected action dispatched by either `requestThunk1` or `requestThunk2`
}
Expand All @@ -121,15 +121,15 @@ A higher-order function that returns a type guard function that may be used to c

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

const isARejectedWithValueAction = isRejectedWithValue(
requestThunk1,
requestThunk2
)

function handleRejectedWithValueAction(action: AnyAction) {
function handleRejectedWithValueAction(action: UnknownAction) {
if (isARejectedWithValueAction(action)) {
// action is a rejected action dispatched by either `requestThunk1` or `requestThunk2`
// where rejectWithValue was used
Expand All @@ -145,10 +145,7 @@ we're able to easily use the same matcher for several cases in a type-safe manne
First, let's examine an unnecessarily complex example:

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

interface Data {
Expand Down
4 changes: 2 additions & 2 deletions docs/rtk-query/api/createApi.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ export const { useGetPokemonByNameQuery } = pokemonApi
baseQuery(args: InternalQueryArgs, api: BaseQueryApi, extraOptions?: DefinitionExtraOptions): any;
endpoints(build: EndpointBuilder<InternalQueryArgs, TagTypes>): Definitions;
extractRehydrationInfo?: (
action: AnyAction,
action: UnknownAction,
{
reducerPath,
}: {
Expand Down Expand Up @@ -88,7 +88,7 @@ export const { useGetPokemonByNameQuery } = pokemonApi
- `dispatch` - The `store.dispatch` method for the corresponding Redux store
- `getState` - A function that may be called to access the current store state
- `extra` - Provided as thunk.extraArgument to the configureStore getDefaultMiddleware option.
- `endpoint` - The name of the endpoint.
- `endpoint` - The name of the endpoint.
- `type` - Type of request (`query` or `mutation`).
- `forced` - Indicates if a query has been forced.
- `extraOptions` - The value of the optional `extraOptions` property provided for a given endpoint
Expand Down
54 changes: 28 additions & 26 deletions docs/rtk-query/api/created-api/api-slice-utils.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ const updateQueryData = (
endpointName: string,
args: any,
updateRecipe: (draft: Draft<CachedState>) => void
) => ThunkAction<PatchCollection, PartialState, any, AnyAction>;
) => ThunkAction<PatchCollection, PartialState, any, UnknownAction>;

interface PatchCollection {
patches: Patch[];
Expand Down Expand Up @@ -119,7 +119,7 @@ const upsertQueryData = <T>(
endpointName: string,
args: any,
newEntryData: T
) => ThunkAction<Promise<CacheEntry<T>>, PartialState, any, AnyAction>;
) => ThunkAction<Promise<CacheEntry<T>>, PartialState, any, UnknownAction>;
```

- **Parameters**
Expand Down Expand Up @@ -156,7 +156,7 @@ const patchQueryData = (
endpointName: string,
args: any
patches: Patch[]
) => ThunkAction<void, PartialState, any, AnyAction>;
) => ThunkAction<void, PartialState, any, UnknownAction>;
```

- **Parameters**
Expand Down Expand Up @@ -203,7 +203,7 @@ const prefetch = (
endpointName: string,
arg: any,
options: PrefetchOptions
) => ThunkAction<void, any, any, AnyAction>;
) => ThunkAction<void, any, any, UnknownAction>;
```

- **Parameters**
Expand All @@ -229,42 +229,44 @@ dispatch(api.util.prefetch('getPosts', undefined, { force: true }))
```

### `selectInvalidatedBy`

#### Signature

```ts no-transpile
function selectInvalidatedBy(
state: RootState,
tags: ReadonlyArray<TagDescription<string>>
): Array<{
endpointName: string
originalArgs: any
queryCacheKey: QueryCacheKey
}>
function selectInvalidatedBy(
state: RootState,
tags: ReadonlyArray<TagDescription<string>>
): Array<{
endpointName: string
originalArgs: any
queryCacheKey: QueryCacheKey
}>
```

- **Parameters**
- `state`: the root state
- `tags`: a readonly array of invalidated tags, where the provided `TagDescription` is one of the strings provided to the [`tagTypes`](../createApi.mdx#tagtypes) property of the api. e.g.
- `[TagType]`
- `[{ type: TagType }]`
- `[{ type: TagType, id: number | string }]`

#### Description

A function that can select query parameters to be invalidated.

The function accepts two arguments
- the root state and
- the cache tags to be invalidated.


- the root state and
- the cache tags to be invalidated.

It returns an array that contains
- the endpoint name,
- the original args and
- the queryCacheKey.


- the endpoint name,
- the original args and
- the queryCacheKey.

#### Example

```ts no-transpile
dispatch(api.util.selectInvalidatedBy(state, ['Post']))
dispatch(api.util.selectInvalidatedBy(state, [{ type: 'Post', id: 1 }]))
Expand Down
4 changes: 2 additions & 2 deletions docs/rtk-query/api/created-api/endpoints.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,12 @@ type InitiateRequestThunk = StartQueryActionCreator | StartMutationActionCreator
type StartQueryActionCreator = (
arg:any,
options?: StartQueryActionCreatorOptions
) => ThunkAction<QueryActionCreatorResult, any, any, AnyAction>;
) => ThunkAction<QueryActionCreatorResult, any, any, UnknownAction>;

type StartMutationActionCreator<D extends MutationDefinition<any, any, any, any>> = (
arg: any
options?: StartMutationActionCreatorOptions
) => ThunkAction<MutationActionCreatorResult<D>, any, any, AnyAction>;
) => ThunkAction<MutationActionCreatorResult<D>, any, any, UnknownAction>;

type SubscriptionOptions = {
/**
Expand Down
2 changes: 1 addition & 1 deletion docs/usage/usage-with-typescript.md
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,7 @@ As the first `matcher` argument to `builder.addMatcher`, a [type predicate](http
As a result, the `action` argument for the second `reducer` argument can be inferred by TypeScript:

```ts
function isNumberValueAction(action: AnyAction): action is PayloadAction<{ value: number }> {
function isNumberValueAction(action: UnknownAction): action is PayloadAction<{ value: number }> {
return typeof action.payload.value === 'number'
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { counterActions, counterSelectors } from './slice'
import {
AnyAction,
UnknownAction,
isAllOf,
isAnyOf,
PayloadAction,
Expand All @@ -11,7 +11,7 @@ import type { AppListenerEffectAPI, AppStartListening } from '../../store'
function shouldStopAsyncTasksOf(id: string) {
return isAllOf(
isAnyOf(counterActions.cancelAsyncUpdates, counterActions.removeCounter),
(action: AnyAction): action is PayloadAction<string> =>
(action: UnknownAction): action is PayloadAction<string> =>
action?.payload === id
)
}
Expand Down
14 changes: 7 additions & 7 deletions packages/toolkit/etc/redux-toolkit.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
```ts
import type { Action } from 'redux'
import type { ActionCreator } from 'redux'
import type { AnyAction } from 'redux'
import type { UnknownAction } from 'redux'
import type { CombinedState } from 'redux'
import { default as createNextState } from 'immer'
import { createSelector } from 'reselect'
Expand Down Expand Up @@ -85,10 +85,10 @@ export interface ActionReducerMapBuilder<State> {
type: Type,
reducer: CaseReducer<State, A>
): ActionReducerMapBuilder<State>
addDefaultCase(reducer: CaseReducer<State, AnyAction>): {}
addDefaultCase(reducer: CaseReducer<State, UnknownAction>): {}
addMatcher<A>(
matcher: TypeGuard<A> | ((action: any) => boolean),
reducer: CaseReducer<State, A extends AnyAction ? A : A & AnyAction>
reducer: CaseReducer<State, A extends Action ? A : A & Action>
): Omit<ActionReducerMapBuilder<State>, 'addCase'>
}

Expand Down Expand Up @@ -191,7 +191,7 @@ export type AsyncThunkPayloadCreatorReturnValue<
>

// @public
export type CaseReducer<S = any, A extends Action = AnyAction> = (
export type CaseReducer<S = any, A extends Action = UnknownAction> = (
state: Draft<S>,
action: A
) => S | void | Draft<S>
Expand Down Expand Up @@ -227,14 +227,14 @@ export type ConfigureEnhancersCallback = (
// @public
export function configureStore<
S = any,
A extends Action = AnyAction,
A extends Action = UnknownAction,
M extends Middlewares<S> = [ThunkMiddlewareFor<S>]
>(options: ConfigureStoreOptions<S, A, M>): EnhancedStore<S, A, M>

// @public
export interface ConfigureStoreOptions<
S = any,
A extends Action = AnyAction,
A extends Action = UnknownAction,
M extends Middlewares<S> = Middlewares<S>
> {
devTools?: boolean | EnhancerOptions
Expand Down Expand Up @@ -352,7 +352,7 @@ export { Draft }
// @public
export interface EnhancedStore<
S = any,
A extends Action = AnyAction,
A extends Action = UnknownAction,
M extends Middlewares<S> = Middlewares<S>
> extends Store<S, A> {
dispatch: Dispatch<A> & DispatchForMiddlewares<M>
Expand Down
Loading