【问题标题】:Redux-thunk ThunkDispatch type fails when passing an interface to `dispatch<ShowSnackbar>({})`将接口传递给`dispatch<ShowSnackbar>({})` 时,Redux-thunk ThunkDispatch 类型失败
【发布时间】:2019-05-17 06:09:46
【问题描述】:

将接口应用到我的 redux thunk 操作的 dispatch() 函数时,错误检查似乎是错误的。 例如,如果我注释掉一个属性,Typescript 会抱怨实际启用的属性,说它丢失了:

...

type ThunkResult<R> = ThunkAction<R, RootState, undefined, Action>;

export interface ShowSnackbar {
  type: string,
  isOpened: boolean
}

export const showSnackbar = (): ThunkResult<void> => (dispatch, getState) => {

    dispatch<ShowSnackbar>({
        // type: 'baz',
        isOpened: true // <-- 'isOpened' does not exist in type 'ThunkAction<ShowSnackbar ...
    });

}

在检查了 redux-thunk ThunkDispatch 类型后,我注意到重载函数的第一个函数声明被忽略,而当我的操作具有注释掉的属性时调用了第二个函数声明(故意引入错误):

export interface ThunkDispatch<S, E, A extends Action> {
  <T extends A>(action: T): T;
  <R>(asyncAction: ThunkAction<R, S, E, A>): R;
}

如果说,我删除&lt;R&gt;(asyncAction: ThunkAction&lt;R, S, E, A&gt;): R;,类型检查恢复正常,TS 会正确警告我:

“类型”在类型 '{ isOpened: true; 中丢失}' 但在类型中是必需的 'ShowSnackbar'。

我已经整理了一个 demo on TS Playground 来演示这个问题。

还是我做错了什么?

谢谢!

【问题讨论】:

    标签: typescript redux typescript-typings redux-thunk


    【解决方案1】:

    TypeScript 在这里会感到困惑,因为它有两种尝试的可能性。如果你切换ThunkDispatch 的顺序,你已经得到了你想首先看到的错误信息:

    export interface ThunkDispatch<S, E, A extends Action> {
      <R>(asyncAction: ThunkAction<R, S, E, A>): R;
      <T extends A>(action: T): T;
    }
    

    '{ isOpened: true; 类型的参数}' 不可分配给“ShowSnackbar”类型的参数。 类型 '{ isOpened: true; 中缺少属性 'type' }' 但在“ShowSnackbar”类型中是必需的。

    顺便说一句:我建议将extends Action&lt;string&gt;(或Action&lt;'baz'&gt;)添加到您的ShowSnackbar 接口并从其定义中删除type: string。这样,您将继续成为Action,即使您后来决定更改操作上的某些内容。或者至少,当您决定将名称 type 更改为其他名称时,您会收到错误消息。

    【讨论】:

    • 是的,这是有道理的。感谢有关我的界面的建议!
    猜你喜欢
    • 1970-01-01
    • 2016-02-12
    • 2017-10-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-18
    • 2020-04-16
    • 2021-08-11
    相关资源
    最近更新 更多