【发布时间】:2020-08-10 14:07:00
【问题描述】:
详情
我正在尝试创建一个辅助函数来将我的减速器组合成一个全局减速器,以便与 react 的 useReducer 钩子和上下文 API 一起使用。我有它的功能,但我目前对类型检查不满意。
问题
为了让它工作,我必须在 Reducers 类型中添加 [key: string]: Reducer<any>,在 GlobalState 类型中添加 [key: string]: any;。如果我删除它们,我会收到错误
元素隐含地具有“任何”类型,因为类型的表达式 'string' 不能用于索引类型 'GlobalState'。无索引 在类型上找到带有“字符串”类型参数的签名 '全球状态'。
元素隐含地具有“任何”类型,因为类型的表达式 'string' 不能用于索引类型'Reducers'。没有索引签名 在“Reducers”类型上找到了“字符串”类型的参数。
这给我留下了一个combineReducers 函数,我可以在其中将状态键命名为任何东西
一个例子
我的初始状态是这样的:{page: {some state}, state2: {some state}}
然后我像这样组合减速器:combineReducers({ pages: pageReducer, state3: reducer2 });
我现在的状态看起来像 {page: {some state}, state2: {some state}}, pages: {some state}, state3: {some state},因为“不小心”将状态键命名错误。
问题
在删除 Reducers 类型中的 [key: string]: Reducer<any> 和 GlobalState 类型中的 [key: string]: any; 时,有没有办法让它工作?
代码
types.ts
export type GlobalReducer = (state: GlobalState, action: Action) => GlobalState;
export type Reducer<State> = (state: State, action: Action) => State;
export type Reducers = {
[key: string]: Reducer<any>;
page: Reducer<PageState>;
state2: Reducer<AnotherState>;
};
export type GlobalState = {
[key: string]: any;
page: PageState;
state2: AnotherState;
};
export type PageState = {
title: string;
loading: true;
};
export type AnotherState = {
hello: string;
};
combineReducers.ts
import _ from "lodash";
import { Action, Reducers, GlobalState, GlobalReducer } from "./types";
const combineReducers = (reducers: Reducers): GlobalReducer => {
return (state: GlobalState, action: Action): GlobalState => {
const reducerKeys = Object.keys(reducers);
reducerKeys.forEach((key) => {
const newState = reducers[key](state[key], action);
state = _.isEqual(newState, state[key]) ? state : { ...state, [key]: newState };
});
return state;
};
};
export { combineReducers };
index.ts
export const globalReducer = combineReducers({ page: pageReducer, state2: reducer2 });
initialState.ts
export const initialState: GlobalState = {
page: {
title: "Holidaze",
loading: true
},
state2: {
hello: ""
}
};
【问题讨论】:
标签: typescript