MapDispatchToProps вызывает ошибку Typescript в родительском компоненте, ожидая, что действия будут переданы как реквизиты - PullRequest
0 голосов
/ 01 января 2019

В моем дочернем компоненте я определяю MapDispatchToProps, передаю их в connect и, соответственно, определяю интерфейс PropsFromDispatch, который расширен в React.Component Props Interface.Теперь в моем родительском компоненте Typescript говорит мне, что ему не хватает свойств, которые я определил в PropsFromDispatch.

Это не кажется абсурдным, так как я определяю их как часть интерфейса React.Component Props,однако я ожидал бы, что 'connect' позаботится об этом так же, как он заботится о моем PropsFromState, который мне также не нужно передавать от родительского к дочернему компоненту, но отображается из состояния в Props.

/ JokeModal.tsx

...

interface Props extends PropsFromState, PropsFromDispatch {
    isOpen: boolean
    renderButton: boolean
}

...

const mapDispatchToProps = (dispatch: Dispatch<any>): 
PropsFromDispatch => {
    return {
        tellJoke: (newJoke: INewJoke) => dispatch(tellJoke(newJoke)),
        clearErrors: () => dispatch(clearErrors())
    }
}

interface PropsFromDispatch {
    tellJoke: (newJoke: INewJoke) => void
    clearErrors: () => void
}

...

export default connect(mapStateToProps, mapDispatchToProps)(JokeModal);

/ Parent.tsx

...

button = <JokeModal isOpen={false} renderButton={true} /> 
...

В этой строке /Parent.tsx Typescript теперь говорит мне:

Type '{ isOpen: false; renderButton: true; }' is missing the 
following properties from type 'Readonly<Pick<Props, "isOpen" | 
"renderButton" | "tellJoke" | "clearErrors">>': tellJoke, clearErrors 
ts(2739)

Интересно, что я могу полностью избежать этой ошибки, удалив MapDispatchToProps и вместо этого передавая действия непосредственно в connect (включая диспетчеризацию уже в создателе действий):

export default connect(mapStateToProps, { tellJoke, clearErrors })(JokeModal);

Тем не менее, я хотел бы знать, какиспользовать MapDispatchToProps здесь, а также почему Typescript ожидает от меня передачи этих действий дочернему компоненту?

Рад услышать ваш совет!

1 Ответ

0 голосов
/ 11 января 2019

Мне удалось воспроизвести вашу проблему, и проблема, по-видимому, связана с сигнатурой типа функции mapDispatchToProps в исходном коде , вы можете видеть, что она имеет параметр типа Action = AnyAction

export interface Dispatch<A extends Action = AnyAction> {
  <T extends A>(action: T): T
}

Решение вашей проблемы состоит в том, чтобы изменить Dispatch<any> на Dispatch<AnyAction>:

const mapDispatchToProps = (dispatch: Dispatch<AnyAction>): PropsFromDispatch

Обратите внимание, что поскольку вы используете redux-thunk, система типов может не позволить вамчтобы вызвать dispatch на thunk, так что вам, возможно, придется либо обмануть, позвонив

clearErrors: () => dispatch<any>(clearErrors());

, либо использовать довольно многословную печать с ThunkDispatch и ThunkAction.У меня есть пример такой печати здесь: ThunkDispatch и соответствующий ThunkAction .Обратите внимание, что я использую typesafe-actions .

...