Skip to content
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

Type action and next as unknown #4519

Merged
merged 3 commits into from
Apr 16, 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
6 changes: 3 additions & 3 deletions src/types/middleware.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,11 @@ export interface MiddlewareAPI<D extends Dispatch = Dispatch, S = any> {
* installed.
*/
export interface Middleware<
_DispatchExt = {}, // TODO: remove unused component (breaking change)
_DispatchExt = {}, // TODO: see if this can be used in type definition somehow (can't be removed, as is used to get final dispatch type)
S = any,
D extends Dispatch = Dispatch
> {
(api: MiddlewareAPI<D, S>): (
next: D
) => (action: D extends Dispatch<infer A> ? A : never) => any
next: (action: unknown) => unknown
) => (action: unknown) => unknown
}
13 changes: 6 additions & 7 deletions test/applyMiddleware.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,10 @@ describe('applyMiddleware', () => {
})

it('wraps dispatch method with middleware once', () => {
function test(spyOnMethods: any) {
return (methods: any) => {
function test(spyOnMethods: any): Middleware {
return methods => {
spyOnMethods(methods)
return (next: Dispatch) => (action: Action) => next(action)
return next => action => next(action)
}
}

Expand All @@ -53,8 +53,8 @@ describe('applyMiddleware', () => {
})

it('passes recursive dispatches through the middleware chain', () => {
function test(spyOnMethods: any) {
return () => (next: Dispatch) => (action: Action) => {
function test(spyOnMethods: any): Middleware {
return () => next => action => {
spyOnMethods(action)
return next(action)
}
Expand Down Expand Up @@ -146,8 +146,7 @@ describe('applyMiddleware', () => {
}

function dummyMiddleware({ dispatch }: MiddlewareAPI) {
return (_next: Dispatch) => (action: Action) =>
dispatch(action, testCallArgs)
return (_next: unknown) => (action: any) => dispatch(action, testCallArgs)
}

const store = createStore(
Expand Down
20 changes: 8 additions & 12 deletions test/helpers/middleware.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,9 @@
import { MiddlewareAPI, Dispatch, AnyAction } from 'redux'
import { Dispatch, Middleware } from 'redux'

type ThunkAction<T extends any = any> = T extends AnyAction
? AnyAction
: T extends Function
? T
: never

export function thunk({ dispatch, getState }: MiddlewareAPI) {
return (next: Dispatch) =>
<_>(action: ThunkAction) =>
typeof action === 'function' ? action(dispatch, getState) : next(action)
}
export const thunk: Middleware<{
<R>(thunk: (dispatch: Dispatch, getState: () => any) => R): R
}> =
({ dispatch, getState }) =>
next =>
action =>
typeof action === 'function' ? action(dispatch, getState) : next(action)
32 changes: 14 additions & 18 deletions test/typescript/middleware.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ import {
*/
function logger() {
const loggerMiddleware: Middleware =
({ getState }: MiddlewareAPI) =>
(next: Dispatch) =>
({ getState }) =>
next =>
action => {
console.log('will dispatch', action)

Expand All @@ -41,9 +41,9 @@ type PromiseDispatch = <T extends Action>(promise: Promise<T>) => Promise<T>

function promise() {
const promiseMiddleware: Middleware<PromiseDispatch> =
({ dispatch }: MiddlewareAPI) =>
({ dispatch }) =>
next =>
<T extends Action>(action: AnyAction | Promise<T>) => {
action => {
if (action instanceof Promise) {
action.then(dispatch)
return action
Expand Down Expand Up @@ -72,13 +72,10 @@ function thunk<S, DispatchExt>() {
ThunkDispatch<S, DispatchExt>,
S,
Dispatch & ThunkDispatch<S>
> =
api =>
(next: Dispatch) =>
<R>(action: AnyAction | Thunk<R, any>) =>
typeof action === 'function'
? action(api.dispatch, api.getState)
: next(action)
> = api => next => action =>
typeof action === 'function'
? action(api.dispatch, api.getState)
: next(action)

return thunkMiddleware
}
Expand All @@ -89,14 +86,13 @@ function thunk<S, DispatchExt>() {
function customState() {
type State = { field: 'string' }

const customMiddleware: Middleware<{}, State> =
api => (next: Dispatch) => action => {
api.getState().field
// @ts-expect-error
api.getState().wrongField
const customMiddleware: Middleware<{}, State> = api => next => action => {
api.getState().field
// @ts-expect-error
api.getState().wrongField

return next(action)
}
return next(action)
}

return customMiddleware
}
Expand Down