ReactJs,带有打字稿的 Redux。键入的 combineReducers 错误

时间:2021-07-08 11:07:44

标签: reactjs typescript redux react-redux

React 应用有多个 redux 切片,reducer 有如下签名

用户减速器:

export const user = (
  state: UserState = initialState,
  action: UserAction
): UserState => {
  .....
};

文档缩减器:

export const document = (
  state: DocumentState = initialState,
  action: DocumentAction
): DocumentState => {
  ....
};

Action 和 State 类型整合如下

export type StoreAction = UserAction | DocumentAction;

export type StoreState = {
  user: UserState;
  document: DocumentState;
};

然后像这样创建根减速器

const rootReducer = combineReducers<StoreState, StoreAction>({
  user,
  document
});

这会在每个通过的 reducer 处产生错误

(property) document: Reducer<DocumentState, any>
Type '(state: DocumentState | undefined, action: DocumentAction) => DocumentState' is not assignable to type 'Reducer<DocumentState, StoreAction>'.
  Types of parameters 'action' and 'action' are incompatible.
    Type 'StoreAction' is not assignable to type 'DocumentAction'.
      Type 'SetUsers' is not assignable to type 'DocumentAction'.
        Type 'SetUsers' is not assignable to type 'ResetDocuments'.
          Types of property 'type' are incompatible.
            Type '"SET_USERS"' is not assignable to type '"RESET_DOCUMENTS"'.ts(2322)
types.ts(9, 3): The expected type comes from property 'document' which is declared here on type 'ReducersMapObject<StoreState, StoreAction>'

(property) user: Reducer<UserState, any>
Type '(state: UserState | undefined, action: UserAction) => UserState' is not assignable to type 'Reducer<UserState, StoreAction>'.
  Types of parameters 'action' and 'action' are incompatible.
    Type 'StoreAction' is not assignable to type 'UserAction'.
      Type 'SetDocuments' is not assignable to type 'UserAction'.
        Type 'SetDocuments' is not assignable to type 'ResetUsers'.
          Types of property 'type' are incompatible.
            Type '"SET_DOCUMENTS"' is not assignable to type '"RESET_USERS"'.ts(2322)
types.ts(8, 3): The expected type comes from property 'user' which is declared here on type 'ReducersMapObject<StoreState, StoreAction>'

我打算使用带有签名的 combinedReducer

export function combineReducers<S, A extends Action = AnyAction>(
  reducers: ReducersMapObject<S, A>
): Reducer<CombinedState<S>, A>

ReducersMapObjects 的类型似乎是问题

export type ReducersMapObject<S = any, A extends Action = Action> = {
  [K in keyof S]: Reducer<S[K], A>
}

似乎每个减速器都应该返回 StoreAction。但这不可能是正确的,或者我在这里做错了什么。

完整示例 here

更新第一个答案。

export type StoreAction = UserAction & DocumentAction;

这有效。但是当我将它应用到我的实际应用中时,它是所有类型的 10 多个切片的交集。

export type StoreAction = Actoin1 & Action2 & ... & Action10;

这看起来太复杂了,因为我出错了。

Expression produces a union type that is too complex to represent.ts

1 个答案:

答案 0 :(得分:2)

这是由 OR 运算符引起的。你需要AND

改成

export type StoreAction = UserAction | DocumentAction;

进入

export type StoreAction = UserAction & DocumentAction;

更新答案

您可以使用TypeScript tuple

export type StoreAction = [Actoin1, Action2, ..., Action10]