Redux与TypeScript类型问题:if判断后仍提示undefined
解决Redux Reducer中TypeScript类型窄化失效问题
问题原因
TypeScript的类型窄化仅对直接引用的变量生效。你原代码中多次通过state.timeline[timelineIndexToModify].elements[elementIndexToModify].availabilities这种嵌套路径访问属性时,TS无法确认每次访问的是同一个对象实例,因此之前的存在性检查无法传递到后续的属性访问中,导致仍提示undefined。
另外原代码还存在潜在的数组越界风险:findIndex可能返回-1,此时直接访问state.timeline[timelineIndexToModify]会引发运行时错误。
解决方案
将深层嵌套的对象提前赋值给局部变量,让TypeScript能跟踪变量的类型窄化结果;同时补充索引有效性的判断,避免越界问题。
修改后的代码如下:
updateAvailabilities(state, action: PayloadAction<Availability>) { const timelineIndexToModify = state.timeline.findIndex(element => { const payloadDay = new Date(action.payload.start).getDate(); const payloadMonth = new Date(action.payload.start).getMonth(); const elementDay = new Date(element.date).getDate(); const elementMonth = new Date(element.date).getMonth(); return payloadDay === elementDay && payloadMonth === elementMonth; }); // 处理未找到对应时间节点的情况 if (timelineIndexToModify === -1) { // 根据业务需求添加逻辑,比如创建新时间节点并插入 return; } // 提取局部变量,让TS跟踪类型 const targetTimeline = state.timeline[timelineIndexToModify]; if (targetTimeline.elements.length === 0) { targetTimeline.elements.push({ availabilities: [{ ...action.payload }] }); } else { const elementIndexToModify = targetTimeline.elements.findIndex(element => !!element.availabilities); if (elementIndexToModify === -1) { targetTimeline.elements.push({ availabilities: [{ ...action.payload }] }); } else { // 提取目标元素数据 const targetElement = targetTimeline.elements[elementIndexToModify]; // 这里的类型窄化会被TS正确识别 if (targetElement.availabilities) { const availabilityIndexToModify = targetElement.availabilities.findIndex( item => item.id === action.payload.id ); // 处理未找到对应可用性数据的情况 if (availabilityIndexToModify !== -1) { targetElement.availabilities[availabilityIndexToModify] = action.payload; } else { // 若未找到,可选择添加新数据(根据业务需求调整) targetElement.availabilities.push(action.payload); } } } } }
修改说明
- 新增
timelineIndexToModify === -1的判断,避免数组越界访问; - 用局部变量
targetTimeline和targetElement存储深层对象引用,让TS能正确跟踪类型窄化结果; - 补充
availabilityIndexToModify !== -1的判断,防止修改不存在的数组项; - 简化
findIndex的判断逻辑,用!!element.availabilities替代冗余的if-else。
内容的提问来源于stack exchange,提问作者Fab
相关产品推荐
相关产品推荐

