最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Typescript error "Property 'then' does not exist" when chaining promises with pro

programmeradmin3浏览0评论

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?

Share Improve this question edited Nov 1, 2017 at 22:32 FuzzyTree asked Nov 1, 2017 at 20:49 FuzzyTreeFuzzyTree 32.4k3 gold badges57 silver badges87 bronze badges 5
  • 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 the Dispatch interface like redux-thunk does... You might need to add the typing information yourself – MinusFour Commented Nov 1, 2017 at 22:27
Add a ment  | 

1 Answer 1

Reset to default 4

As 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.

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论