我有一个状态类型,以及一个消息处理程序(thunk)的对象,它的类型明确为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 }))
}
})
}
Run Code Online (Sandbox Code Playgroud)
不过我觉得else if最后可以写得更简洁一些。
else if (getState().data[key])有效(如果我忽略它),但 TypeScript 抱怨:
元素隐式具有“any”类型,因为“string”类型的表达式不能用于索引类型“{ startRequestCounter: number;” 启动响应计数器:数字;停止请求计数器:数字;停止响应计数器:数字;比色杯计数:数量;移液器计数:数量;机器人模式:机器人模式;}'。
我做了一些搜索,看起来可能keyof就是我要找的东西,但当keyof我输入它时却找不到。
这是因为 key 不能保证是您的DataState.
您可以告诉 TypeScript 它将使用keyof.
if (getState().data[key]) {
// Error Here
}
if (getState().data[key as keyof DataState]) {
// Not Here
}
Run Code Online (Sandbox Code Playgroud)