[Typescript] Unable to create a slice creator with thunk
See original GitHub issueI’m trying to build a function that return a slice and thunk, which will use generic type, here’s a minimal code snippet:
import { createSlice, PayloadAction } from '@reduxjs/toolkit'
export interface _State {
status: 'NOT_LOADED' | 'LOADING' | 'LOADED' | 'ERROR';
error?: string;
}
const createNrSlice = <Parameter extends object>() => {
const startFetch = (
state: _State,
action: PayloadAction<Parameter>
) => {
console.log(action)
}
const fetchFailed = (
state: _State,
action: PayloadAction<string>
) => {
console.log(action)
}
const initialState: _State = {
status: 'NOT_LOADED',
};
const slice = createSlice({
name: 'testSlice',
initialState,
reducers: {
start: startFetch,
failed: fetchFailed,
}
})
slice.actions.start({} as Parameter) // ERROR
slice.actions.failed('') // PASS
}
/*
ERROR MESSAGE:
~~~~~~~~~~~~~~~
This expression is not callable.
Each member of the union type 'ActionCreatorWithPayload<any, string> | ActionCreatorWithNonInferrablePayload<string> | ActionCreatorWithoutPayload<string> | ActionCreatorWithOptionalPayload<...> | ActionCreatorWithPayload<...>' has signatures, but none of those signatures are compatible with each other.ts(2349)
*/
slice.action.start
is expected to be something like ActionCreatorWithPayload<Parameter>(payload: Parameter)
but I just got an error.
It’s okay if i call slice.actions.start
outside the createNrSlice
function, but if I call it inside the function, there will be an error.
The problem is if I want to make a function return both a slice and a thunk, I must call actions inside the function.
We’ve discussed a lot about this problem in the Redux discord channel but got no result, and would like to know if it’s a bug related to the TypeScript definition.
Note: Remove extends object
near <Parameter extends object>()
won’t solve the problem.
Issue Analytics
- State:
- Created 4 years ago
- Comments:14 (7 by maintainers)
@phryneas Sorry, but another question about TypeScript…
I modified a little from the official example, trying to make reducer an optional parameter, and the generic type break again:
(diff attached)
My question is: Why turn the type of additional
reducers
to optional will change the type of actionsWhile using wrapped
createSlice
, users must always provide a reducer even if it’s not necessary?Diff
Thanks for your help! But you know… It looks so dirty… hope TypeScript could merge the PR mentioned on your twitter as soon as possible…
Update:
The code that works would looks like this:
Really complex anyway…