I'm using redux-promise-middleware with redux-thunk in order to chain my promises:
import { Dispatch } from 'redux';
class Actions {
private static _dispatcher: Dispatch<any>;
public static get dispatcher(): Dispatch<any> {
return Actions._dispatcher;
}
public static test() {
this.dispatcher({
type: 'MY_ACTION',
payload: new Promise(resolve => resolve('hi'));
}).then(result => {
console.log(result); // this works
});
}
}
The code above works but also generates a warning during pile time:
TS2339: Property 'then' does not exist on type '{ type: string; payload: Promise<{}>; }'
It sounds like I need to include Promise<...>
somewhere as a type so typescript knows that then
is in fact a property on the object that's returned by dispatcher()
but I haven't been able to remove the error.
import { Dispatch } from 'redux';
import { ThunkAction } from 'redux-thunk';
import { getStore, IState } from './my_store';
let store = getStore();
// Create myThunkAction function with a type of ThunkAction<R, S, E>
let myThunkAction: ThunkAction<Promise<string>, IState, null> =
(dispatch: Dispatch<IState>, getState: () => IState) => {
return new Promise<string>((resolve, reject) => {
// do async stuff with getState() and dispatch(), then...
resolve('done!');
});
}
store.dispatch(myThunkAction)
.then(() => {
// do stuff after the thunk has finished...
});
Seems related but where I can specify the action type i.e. MY_ACTION
?
I'm using redux-promise-middleware with redux-thunk in order to chain my promises:
import { Dispatch } from 'redux';
class Actions {
private static _dispatcher: Dispatch<any>;
public static get dispatcher(): Dispatch<any> {
return Actions._dispatcher;
}
public static test() {
this.dispatcher({
type: 'MY_ACTION',
payload: new Promise(resolve => resolve('hi'));
}).then(result => {
console.log(result); // this works
});
}
}
The code above works but also generates a warning during pile time:
TS2339: Property 'then' does not exist on type '{ type: string; payload: Promise<{}>; }'
It sounds like I need to include Promise<...>
somewhere as a type so typescript knows that then
is in fact a property on the object that's returned by dispatcher()
but I haven't been able to remove the error.
https://github./gaearon/redux-thunk/issues/103
import { Dispatch } from 'redux';
import { ThunkAction } from 'redux-thunk';
import { getStore, IState } from './my_store';
let store = getStore();
// Create myThunkAction function with a type of ThunkAction<R, S, E>
let myThunkAction: ThunkAction<Promise<string>, IState, null> =
(dispatch: Dispatch<IState>, getState: () => IState) => {
return new Promise<string>((resolve, reject) => {
// do async stuff with getState() and dispatch(), then...
resolve('done!');
});
}
store.dispatch(myThunkAction)
.then(() => {
// do stuff after the thunk has finished...
});
Seems related but where I can specify the action type i.e. MY_ACTION
?
-
dispatcher(): Dispatch<any>
why? – Aluan Haddad Commented Nov 1, 2017 at 20:53 -
We need the code for
dispatcher
– MinusFour Commented Nov 1, 2017 at 21:04 -
What is
Actions._dispatcher
? – MinusFour Commented Nov 1, 2017 at 22:02 -
@MinusFour it is
(action: any) => store.dispatch(action)
– FuzzyTree Commented Nov 1, 2017 at 22:08 -
1
I don't see any types for
redux-promise-middleware
in their github and the@types/redux-promise-middleware
doesn't offer any extra typing on theDispatch
interface likeredux-thunk
does... You might need to add the typing information yourself – MinusFour Commented Nov 1, 2017 at 22:27
1 Answer
Reset to default 4As you can see in this ts playground the variable a
exposes the same keys as the type ofDispatch<any>
, and as you can see if you mouse over the error, the error message is the same as in your case. In order to access the promise (and there for the then
function) you will have to access the payload
of the Dispatch object.
this.dispatcher({ ... }).payload.then(....);
Edit1:
If we take a look at the typings for redux we can quite quickly find the Dispatcher interface.
export interface Dispatch<S> {
<A extends Action>(action: A): A;
}
export interface Action {
type: any;
}
And then through some rewriting and some liberal use of psudocode, we can deduct that the type of Dispatch is a function that takes one argument witch is an object and returns an object of the same type as the argument.
type Dispatch: (action: {type: any, ...}) => {type: any, ...}
Both the input object and the output object is of the type:
interface {
type: any,
[key: string]: value
}
In conclusion, either 1) you are not using the official typings for redux, 2) the official typings for redux is wrong, or 3) you have missed something in your live environment were in fact the code doesn't work.
Edit2:
I haven't tried this code, so i have no idea if it will actually solve your problem. But you could try to redefine the Dispatch interface.
declare module 'redux' {
export interface Action {
type: any;
}
export interface Dispatch<S> {
<A extends Action>(action: A): Promise<S>;
}
}
It is valid typescript as you can see in this playground, but I haven't had to do this my self before, so this might not work out of the box.
If that doesn't work you could try defining a namespace with the same name as the module.
namespace redux {
export interface Action {
type: any;
}
export interface Dispatch<S> {
<A extends Action>(action: A): Promise<S>;
}
}
Still I haven't tried this before, so I cant guarantee it will work.