Ошибка машинописного текста. Свойство then не существует при связывании обещаний с промежуточным программным обеспечением Promise + thunk

Я использую redux-prom-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; полезная нагрузка: 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?


person FuzzyTree    schedule 01.11.2017    source источник
comment
dispatcher(): Dispatch<any> почему?   -  person Aluan Haddad    schedule 01.11.2017
comment
Нам нужен код для dispatcher   -  person MinusFour    schedule 02.11.2017
comment
Что такое Actions._dispatcher?   -  person MinusFour    schedule 02.11.2017
comment
@MinusFour это (action: any) => store.dispatch(action)   -  person FuzzyTree    schedule 02.11.2017
comment
Я не вижу типов для redux-promise-middleware в их github, а @types/redux-promise-middleware не предлагает никакого дополнительного набора текста в интерфейсе Dispatch, как это делает redux-thunk ... Возможно, вам придется добавить информацию о вводе самостоятельно   -  person MinusFour    schedule 02.11.2017


Ответы (1)


Как видите, на этой игровой площадке переменная a предоставляет те же ключи, что и тип ofDispatch<any>, и, как вы можете видеть, если вы наведете указатель мыши на ошибку, сообщение об ошибке будет таким же, как и в вашем случае. Чтобы получить доступ к обещанию (и к функции then), вам нужно будет получить доступ к payload объекта Dispatch.

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

Редактировать1:

Если мы посмотрим на типизацию для redux, мы сможем довольно быстро нахожу интерфейс Диспетчера.

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

А затем путем некоторого переписывания и некоторого либерального использования псудокода мы можем сделать вывод, что тип Dispatch - это функция, которая принимает один аргумент, который является объектом, и возвращает объект того же типа, что и аргумент.

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

И входной, и выходной объект имеют тип:

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

В заключение, либо 1) вы не используете официальную типизацию для redux, 2) официальная типизация для redux неверна, или 3) вы что-то пропустили в своей живой среде, но на самом деле код не работает.

Edit2:

Я не пробовал этот код, поэтому понятия не имею, решит ли он вашу проблему. Но вы можете попробовать переопределить интерфейс диспетчеризации.

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

Это действительный машинописный текст, как вы можете видеть в эта площадка, но мне раньше не приходилось делать это самому, так что это может не сработать из коробки.

Если это не сработает, вы можете попробовать определить пространство имен с тем же именем, что и модуль.

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

Тем не менее, я не пробовал это раньше, поэтому не могу гарантировать, что это сработает.

person Olian04    schedule 01.11.2017
comment
Использование .payload.then вместо .then приводит к нарушению кода, т.е. Cannot read property 'then' of undefined. Чтобы было ясно, код, который я опубликовал, работает, но показывает ошибку, которую я хочу устранить. - person FuzzyTree; 02.11.2017
comment
@FuzzyTree Тогда, боюсь, вам придется более конкретно указать, где возникает ваша ошибка. Поскольку в сообщении об ошибке, которое вы предоставили, говорится, что ошибка возникает при попытке доступа к методу с именем then для объекта типа { type: string; payload: Promise<{}>; }. А поскольку в коде, который вы предоставили, есть только одно вхождение термина then, можно было бы предположить, что это было место в коде, из которого возникла ошибка. - person Olian04; 02.11.2017
comment
Ошибка определенно вызвана предоставленным кодом, но она возникает только во время компиляции, когда машинописный текст выполняет проверку типа. Во время выполнения все работает правильно, и я могу видеть результат обещания. Я предполагаю, что мой тип dispatcher неверен, поэтому машинописный текст не знает, что он возвращает обещание и что then доступен - person FuzzyTree; 02.11.2017
comment
@FuzzyTree Не могли бы вы указать свой dispatcher тип? - person Olian04; 02.11.2017
comment
Это redux.Dispatch<any>. Извините, я новичок в машинописном тексте, поэтому дайте мне знать, могу ли я предоставить дополнительную информацию - person FuzzyTree; 02.11.2017
comment
@FuzzyTree Пожалуйста, ознакомьтесь с моими последними изменениями. Кроме того, не беспокойтесь о том, что вы новичок. Машинопись - очень мощный инструмент, но для полного понимания требуется время. - person Olian04; 02.11.2017
comment
Я считаю, что промежуточное ПО redux-thunk меняет то, что возвращает Dispatch - person FuzzyTree; 02.11.2017
comment
@FuzzyTree. В этом случае вам нужно будет набрать для redux-thunk, однако я считаю, что это выходит за рамки этой цепочки вопросов :) Не стесняйтесь принять мой ответ (нажмите галочку), если вы считаете, что он был полезен. - person Olian04; 02.11.2017
comment
Я упомянул redux-thunk с самого начала, так что он входит в сферу применения;). Однако вы были полезны, поэтому я поддержал ваш ответ. - person FuzzyTree; 02.11.2017