You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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);
        }
      }
    }
  }
}

修改说明

  1. 新增timelineIndexToModify === -1的判断,避免数组越界访问;
  2. 用局部变量targetTimeline和targetElement存储深层对象引用,让TS能正确跟踪类型窄化结果;
  3. 补充availabilityIndexToModify !== -1的判断,防止修改不存在的数组项;
  4. 简化findIndex的判断逻辑,用!!element.availabilities替代冗余的if-else。

内容的提问来源于stack exchange,提问作者Fab

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 14:22:28