I'm experiencing a typescript error on my container component when trying to create my mapDispatchToProps function because my Thunk function doesn't return an object with property 'Type' in it. My Thunk returns a Promise, which itself doesn't have the 'Type' property, but does dispatch an action that does have 'Type' in it. I'm not sure how to tell typescript that this is ok.
The error I get is
Argument of type '(dispatch: Dispatch<ActionTypes>, getState: () => IStoreState) => Promise<void>' is not assignable to parameter of type 'ActionTypes'.
Property 'type' is missing in type '(dispatch: Dispatch<ActionTypes>, getState: () => IStoreState) => Promise<void>'.
Action Types:
export interface IFetchJokeSuccessAction {
readonly type: ActionTypeKeys.FETCH_JOKE_SUCCESS;
readonly payload: string;
}
export interface IFetchJokeInProgressAction {
payload: string;
readonly type: ActionTypeKeys.FETCH_JOKE_INPROGRESS
}
export interface IFetchJokeFailAction {
readonly type: ActionTypeKeys.FETCH_JOKE_FAIL;
readonly payload: string;
}
export interface IClearJokeAction {
readonly type: ActionTypeKeys.CLEAR_JOKE
}
type ActionTypes = IFetchJokeSuccessAction | IFetchJokeInProgressAction | IFetchJokeFailAction | IClearJokeAction;
Here's my dispatch on my component:
interface IDispatchProps {
clearJoke: () => any;
fetchJoke: () => any;
}
const mapDispatchToProps = (dispatch: Dispatch<ActionTypes>): IDispatchProps => {
return {
clearJoke: () => dispatch(clearJoke()), // No problem, this is a regular action
fetchJoke: () => dispatch(fetchJoke()) // Problem, this is a Thunk
}
};
Here are my actions:
import { Dispatch } from 'redux';
import { fetchJokeAPI } from '../api/jokeApi';
import IStoreState from '../store/IStoreState';
import { ActionTypeKeys as keys, ActionTypes, IClearJokeAction, IFetchJokeFailAction, IFetchJokeInProgressAction, IFetchJokeSuccessAction} from './ActionTypes';
export function fetchJoke(): (dispatch: Dispatch<ActionTypes>, getState: () => IStoreState) => Promise<void> {
return async (dispatch: Dispatch<IFetchJokeInProgressAction | IFetchJokeSuccessAction | IFetchJokeFailAction>, getState: () => IStoreState) => {
dispatch(fetchJokeInProgress())
try {
const jokePayload = await fetchJokeAPI();
dispatch(fetchJokeSuccess(jokePayload));
} catch (err) {
dispatch(fetchJokeFail(err));
}
}
}
export function fetchJokeSuccess(payload: string): IFetchJokeSuccessAction {
return {
payload,
type: keys.FETCH_JOKE_SUCCESS,
}
}
export function fetchJokeInProgress(): IFetchJokeInProgressAction {
return {
payload: 'Fetching a good joke.',
type: keys.FETCH_JOKE_INPROGRESS
}
}
export function fetchJokeFail(error: Error): IFetchJokeFailAction {
return {
payload: JSON.stringify(error),
type: keys.FETCH_JOKE_FAIL
}
}
export function fetchJoke(): (dispatch: Dispatch<ActionTypes>, getState: () => IStoreState) => Promise<void> {
return async (dispatch: Dispatch<IFetchJokeInProgressAction | IFetchJokeSuccessAction | IFetchJokeFailAction>, getState: () => IStoreState) => {
dispatch(fetchJokeInProgress())
try {
const jokePayload = await fetchJokeAPI();
dispatch(fetchJokeSuccess(jokePayload));
} catch (err) {
dispatch(fetchJokeFail(err));
}
}
}
Since this will be a thunk action creator you have to specify what type of action creator fetchJoke()
is. you are using thunk action creator, but there is not any thunk type in your code.
You are saying that you are returnin Promise<void>
but you have no return
used in the function.
import { ThunkAction } from "redux-thunk";
import { Dispatch, ActionCreator } from "redux";
export const fetchJoke():ActionCreator<
ThunkAction<
Promise<IFetchJokeSuccessAction|IFetchJokeFailAction>, //return value
StoreState, // your app's store
null, // this is extraArgument is passed to the thunk to fetch data
IFetchJokeSuccessAction|IFetchJokeFailAction // which actions you are using in this thunk func
>
> =()=> {
return async (dispatch: Dispatch<ActionTypes>, getState: () => IStoreState) => {
dispatch(fetchJokeInProgress())
try {
const jokePayload = await fetchJokeAPI();
if(jokePayload){
// jokePayload could be undefined. setting type guard
return dispatch(fetchJokeSuccess(jokePayload));
}
} catch (err) {
return dispatch(fetchJokeFail(err));
}
}
}
type ActionTypes = IFetchJokeSuccessAction | IFetchJokeInProgressAction | IFetchJokeFailAction | IClearJokeAction;
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.