首页 文章

使用promise-middleware thunk链接promise时,Typescript错误“属性'then'不存在”

提问于
浏览
1

我正在使用redux-promise-middleware和redux-thunk来实现我的承诺:

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
        });
    }
}

上面的代码有效但在编译期间也会生成警告:

TS2339:属性'then'在类型'{type:string; payload:Promise <{}>; }”

听起来我需要将 Promise<...> 包含在某个类型中,因此打字稿知道 then 实际上是 dispatcher() 返回的对象上的属性,但我无法删除错误 .

https://github.com/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...
});

似乎相关,但我可以指定行动类型,即 MY_ACTION

1 回答

  • 2

    正如您所看到的那样in this ts playground变量 a 公开了与 Dispatch<any> 类型相同的键,正如您可以看到的那样,如果您将鼠标悬停在错误上,则错误消息与您的情况相同 . 为了访问promise(以及 then 函数),您必须访问Dispatch对象的 payload .

    this.dispatcher({ ... }).payload.then(....);
    

    Edit1:

    如果我们看一下typings for redux,我们可以很快找到Dispatcher接口 .

    export interface Dispatch<S> {
        <A extends Action>(action: A): A;
    }
    export interface Action {
      type: any;
    }
    

    然后通过一些重写和一些自由使用的psudocode,我们可以推断出Dispatch的类型是一个函数,它接受一个参数巫婆是一个对象并返回一个与参数相同类型的对象 .

    type Dispatch: (action: {type: any, ...}) => {type: any, ...}
    

    输入对象和输出对象都是以下类型:

    interface {
        type: any,
        [key: string]: value
    }
    

    总而言之,1)你没有使用redux的官方类型,2)redux的官方输入是错误的,或3)你在你的实时环境中错过了一些事实上代码不起作用 .

    Edit2:

    我没有尝试过这段代码,所以我不知道它是否能真正解决你的问题 . 但您可以尝试重新定义Dispatch接口 .

    declare module 'redux' {
        export interface Action {
           type: any;
        }
        export interface Dispatch<S> {
            <A extends Action>(action: A): Promise<S>;
        }
    }
    

    这是有效的打字稿,你可以在this playground中看到,但我之前没有必须这样做,所以这可能无法开箱即用 .

    如果这不起作用,您可以尝试定义与模块同名的命名空间 .

    namespace redux {
        export interface Action {
           type: any;
        }
        export interface Dispatch<S> {
            <A extends Action>(action: A): Promise<S>;
        }
    }
    

    我以前还没有尝试过,所以我不能保证它会起作用 .

相关问题