typescript - TypeScript:删除索引签名而不隐式出现“任何”类型错误
问题描述
细节
我正在尝试创建一个辅助函数来组合我的减速器,以使全局减速器与反应的useReducer
钩子和上下文 API 一起使用。我有它的功能,但我目前对类型检查不满意。
问题
为了让它工作,我必须添加Reducers 类型[key: string]: Reducer<any>
和[key: string]: any;
GlobalState 类型。如果我删除它们,我会收到错误
元素隐含地具有“任何”类型,因为“字符串”类型的表达式不能用于索引类型“全局状态”。在“GlobalState”类型上找不到具有“字符串”类型参数的索引签名。
元素隐含地具有“any”类型,因为“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}
因为“意外地”错误地命名了状态键。
问题
[key: string]: Reducer<any>
在 Reducers 类型和GlobalState 类型中删除时,有没有办法[key: string]: any;
让它工作?
代码
类型.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 };
索引.ts
export const globalReducer = combineReducers({ page: pageReducer, state2: reducer2 });
初始状态.ts
export const initialState: GlobalState = {
page: {
title: "Holidaze",
loading: true
},
state2: {
hello: ""
}
};
解决方案
Object.keys
返回一个字符串数组。您必须转换为keyof Reducers
.
const reducerKeys = Object.keys(reducers) as (keyof Reducers)[];
type GlobalState = {
page: State1,
anotherPage: AnotherState,
}
type GlobalReducer<State> = (state: State, action: Action) => State;
type Reducer<State> = (state: State, action: Action) => State;
type Reducers<State> = { [K in keyof State]: Reducer<State[K]> }
const combineReducers = <State>(reducers: Reducers<State>): GlobalReducer<State> => {
return (state: State, action: Action): State => {
const reducerKeys = Object.keys(reducers) as (keyof State)[];
reducerKeys.forEach((key) => {
const newState = reducers[key](state[key], action);
state = _.isEqual(newState, state[key]) ? state : { ...state, [key]: newState };
});
return state;
};
};
推荐阅读
- android - 将项目上传到 GitHub 时重复项目文件夹
- python-3.x - 运行时错误 R6034,在 Windows 7 上为 Python3 安装 OpenCV 后
- swift - 具有长 JSON 数据的多个 Alamofire 请求问题
- python - Python:find_all 仅适用于某些标签
- django - Django queries using a list
- uwp - UWP BitmapImage.Source - 网络 Uri 工作,但本地磁盘 Uri 不工作
- r - 闪亮:当 eventReactive 函数将另一个 eventReactive 函数的输出作为输入时,ignoreNULL 不起作用?
- java - 分类器和下游和只使用分类器有什么区别
- python - 与重复索引合并 - 行数大于预期
- c++ - 如何组织与两个对象有关的变量