【问题标题】:ReactJs, Redux with typescript. Typed combineReducers errorReactJs,带有打字稿的 Redux。键入 combineReducers 错误
【发布时间】:2021-07-08 11:07:44
【问题描述】:

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

用户减速器:

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
});

这会在每个通过的减速器处产生错误

(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

【问题讨论】:

    标签: reactjs typescript redux react-redux


    【解决方案1】:

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

    改成

    export type StoreAction = UserAction | DocumentAction;
    

    进入

    export type StoreAction = UserAction & DocumentAction;
    

    更新答案

    您可以使用TypeScript tuple

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

    【讨论】:

    • 这在示例中有效,但在我的实际应用中,有超过 10 个切片。所以结合所有给我Expression produces a union type that is too complex to represent.ts(2590)错误
    • 无法使用相同的代码进行更新,但我添加了示例代码。
    • 感谢您的更新。你能解释一下为什么它应该是intersection 而不是union。操作类型是任何操作权。所以这是我所看到的工会。 Intersection 与 ReducersMapObject 类型的定义方式一起使用。但我想知道它是否正确。
    猜你喜欢
    • 2017-09-29
    • 1970-01-01
    • 2018-09-29
    • 1970-01-01
    • 1970-01-01
    • 2018-09-04
    • 2016-08-08
    • 1970-01-01
    • 2021-11-01
    相关资源
    最近更新 更多