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

TypeScript报错:reduce返回对象与IData类型不匹配

TypeScript函数返回类型不匹配问题解决

问题说明

函数返回的对象类型与定义的IData接口不匹配,报错提示year属性类型不兼容——字符串类型无法赋值给数字类型。


相关代码

类型定义与函数实现

export interface IData {
  year?: number;
  days?: {
    day?: number;
    value?: number;
  }[];
}

interface SomeData {
  from: string;
  value: number;
};

const convertToChartData = (data?: SomeData[]): IData[] => {
  if (data && data.length > 0) {
    return Object.entries(
      data.reduce(
        (
          acc: Record<
            number,
            { day: number; value: number | undefined }[]
          >,
          { from, value }
        ) => {
          const [y, d] = from?.split("-").map(Number) ?? [];
          if (!acc[y]) {
            acc[y] = [];
          }
          acc[y].push({ day: d, value });

          return acc;
        },
        {}
      )
    ).map(([year, days]) => ({ year, days }));
  } else return [];
};

函数实际返回示例

[
  { year: '2020', days: [ { day: 1, value: 12 }, {day: 2, value: 1} ] },
  { year: '2021', days: [ { day: 1, value: 132 }, ... ] }
]

编辑器报错信息

{
  year: string;   
   days: {     
     day: number;     
     value: number | undefined;   
   }[]; 
}[]

is not assignable to IData[]

{
  year: string;   
  days: {     
     day: number;     
     value: number | undefined;   
   }[]; 
}

Types of property year are incompatible.
Type string is not assignable to type number

问题原因与修复方案

核心原因

Object.entries() 返回的键始终是字符串类型,哪怕原对象的键是数字。所以遍历后得到的year是字符串,和IData接口中year?: number的类型要求冲突。此外,reduce初始值{}的类型推断和标注的Record<number, ...>不一致,也会埋下隐患。

修复后的代码

const convertToChartData = (data?: SomeData[]): IData[] => {
  if (!data?.length) return [];

  return Object.entries(
    data.reduce((acc, { from, value }) => {
      const [yearStr, dayStr] = from.split("-");
      // 转换并校验年份、日期是否为有效数字
      const year = Number(yearStr);
      const day = Number(dayStr);
      if (isNaN(year) || isNaN(day)) return acc;

      if (!acc[year]) {
        acc[year] = [];
      }
      acc[year].push({ day, value });

      return acc;
    }, {} as Record<number, { day: number; value: number }[]>)
  ).map(([yearStr, days]) => ({
    // 将字符串年份转为数字,匹配接口类型
    year: Number(yearStr),
    days
  }));
};

修复要点

  1. 类型转换:在map阶段把yearStr通过Number()转为数字,对齐IData的类型要求
  2. 类型断言:给reduce的初始值{}加上as Record<number, ...>,明确对象键的类型
  3. 数据校验:过滤转换后为NaN的无效年份和日期,避免无效数据进入结果
  4. 逻辑简化:用!data?.length简化空数组判断,代码更简洁

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 07:01:15