我有一个状态类型,以及一个消息处理程序对象(thunks),它被明确地定义为 Record<string, (val: any) => AppThunk>
我收到的传入消息是对象,它们的键可以与消息处理程序对象的键对应,这种情况下我想调用消息处理程序;或者它们的键可以与 DataState
的键对应,这种情况下我只想将它们发送到 updateState
。
以下代码运行正常。
type DataState = {
startRequestCounter: -1,
startResponseCounter: -1,
stopRequestCounter: -1,
stopResponseCounter: -1,
robotMode: RobotMode.Idle as RobotMode,
}
const messageHandlers: Record<string, (val: any) => AppThunk> = {
startRequestCounter: () => async (dispatch, getState) => // do stuff,
startResponseCounter: (counter: number) => dispatch => // do stuff,
stopResponseCounter: (counter: number) => dispatch => // do stuff
}
export const handleMessage = (message: MessagePayload): AppThunk => (dispatch, getState) => {
Object.entries(message).forEach(([snakeKey, value]) => {
const key = camelCase(snakeKey)
// call the message handler for this message, if there is one
if (messageHandlers[key]) {
dispatch(messageHandlers[key](value))
}
// if not, update the state if we have a state for this message
else if (Object.keys(getState().data).includes(key)) { // <~~~~ HERE!!!!
dispatch(updateState({ [key]: value }))
}
})
}
然而,我觉得末尾的else if
可以更简洁地写成:
else if (getState().data[key])
是可行的(如果我忽略TypeScript的错误提示), 但TypeScript会有如下投诉:
表达式类型为“string”的元素隐含具有“any”类型,因为在类型“{ startRequestCounter: number; startResponseCounter: number; stopRequestCounter: number; stopResponseCounter: number; cuvettesCount: number; pipettesCount: number; robotMode: RobotMode; }”上不能使用字符串索引。
经过一番搜索,我发现keyof
可能是我要找的,但是当我输入它时,却找不到keyof
的定义。
obj[key]
之前,检查if (obj[key])
,您的解决方案在这种情况下有效。 - BobtheMagicMoose