Reducer 自定义调度类型,不可分配,属性 ‘dispatch’ 的类型不兼容

Reducer Custom Dispatch Type, is not assignable, Types of property ‘dispatch’ are incompatible

我现在有一个简单的减速器和动作类型。在设置我的测试时,我 运行 遇到类型定义问题,我的 store 的 return 参考了我的“自定义”操作类型声明。我看到一个错误:

Type ‘Store<CombinedState<{ global: GlobalStateShape; }>, SetSelectedAccount >’ is not assignable to type ‘Store<any, AnyAction>’. Types of property ‘dispatch’ are incompatible

我已正确遵循Redux Typescript docs AFAIK。

为什么当我调用 combineReducers()SetSelectedAccount 被 return 编辑? globalReducer 正在处理 SetSelectedAccount.

的操作

在我的测试设置文件中 出现上述错误的地方:

export function createTestStore(isInternal: boolean): Store {
  const store: Store<CombinedState<{
    global: GlobalStateShape;
    }>, SetSelectedAccount> = createStore(rootReducer, { global: 
     getGlobalInitialState(isInternal) });
  return store;
}

src/reducer.ts

export const rootReducer: Reducer<CombinedState<{
    global: GlobalStateShape;
}>, SetSelectedAccount> = combineReducers({
  global: globalReducer,
});

src/store.ts

const composedEnhancer = composeWithDevTools(
  applyMiddleware()
);

export const store: Store<CombinedState<{
  global: GlobalStateShape;
}>, SetSelectedAccount> = createStore(rootReducer, composedEnhancer);

global_reducer.ts:

export const globalReducer = (
  state = GLOBAL_INITIAL_STATE,
  action: GlobalActionTypes
): GlobalStateShape =>
  produce(state, draft => {
    switch (action.type) {
      case GlobalActions.SET_SELECTED_ACCOUNT: {
        draft.selectedAccountId = action.payload.accountId;
        break;
      }
    }
  });

actions.ts

const SET_SELECTED_ACCOUNT = 'SET_SELECTED_ACCOUNT';

export const GlobalActions = {
  SET_SELECTED_ACCOUNT,
};

export interface SetSelectedAccount {
  type: typeof SET_SELECTED_ACCOUNT;
  payload: { accountId: string; selectedApp: AppsList };
}

export type GlobalActionTypes = SetSelectedAccount;

FWIW,如果我添加第二个操作,则 SetSelectedAccount 变成 GlobalActionTypes 上面的 returned 类型,这是相同的结果和关于不匹配的错误消息 dispatch

谢谢!

问题

问题出在 createTestStore 函数上的 return 类型。您创建了一个特定类型 (Store<CombinedState<{ global: GlobalStateShape; }>, SetSelectedAccount >) 的商店,然后您 return 将其作为没有泛型的 Store 进行处理。 Store 的默认类型是您在错误消息中看到的 Store<any, AnyAction>

您可能认为这不是问题,因为您的商店更具体,所以它应该可以分配给 Store,对吗?但是当你处理像 Dispatch 这样的函数参数时,特异性就会倒退。 return 类型表示您正在 return 一个能够调度 AnyAction 的商店,但实际上您只能调度 SetSelectedAccount 类型,所以您的商店不能分配给更广泛的类型。

解决方案

最简单的方法就是完全删除 return 类型 : State。您已经输入了正在 return 的 store 变量,因此您并不真的需要它。

您还可以将类型注释从变量 store 移动到函数 return。仅供参考,redux CombinedState 实用程序类型实际上没有做任何事情,CombinedState<{ global: GlobalStateShape; }>{ global: GlobalStateShape; }

相同
export function createTestStore(isInternal: boolean): Store<{ global: GlobalStateShape; }, SetSelectedAccount> {
    return createStore(rootReducer, {
        global: getGlobalInitialState(isInternal)
    });
}