将接口传递给 `dispatch<ShowSnackbar>({})` 时,Redux-thunk ThunkDispatch 类型失败

Redux-thunk ThunkDispatch type fails when passing an interface to `dispatch<ShowSnackbar>({})`

将接口应用到我的 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;
}

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

'type' is missing in type '{ isOpened: true; }' but required in type 'ShowSnackbar'.

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

还是我做错了什么?

谢谢!

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

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

Argument of type '{ isOpened: true; }' is not assignable to parameter of type 'ShowSnackbar'. Property 'type' is missing in type '{ isOpened: true; }' but required in type 'ShowSnackbar'.

顺便说一句:我建议将 extends Action<string>(或 Action<'baz'>)添加到您的 ShowSnackbar 界面并从其定义中删除 type: string。这样,即使您稍后决定更改 Action 中的某些内容,您仍将是 Action。或者至少,当您决定将名称 type 更改为其他名称时,您会收到错误消息。