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 })); };
修复要点
- 类型转换:在
map阶段把yearStr通过Number()转为数字,对齐IData的类型要求 - 类型断言:给
reduce的初始值{}加上as Record<number, ...>,明确对象键的类型 - 数据校验:过滤转换后为
NaN的无效年份和日期,避免无效数据进入结果 - 逻辑简化:用
!data?.length简化空数组判断,代码更简洁
内容的提问来源于stack exchange,提问作者Julia
相关产品推荐
相关产品推荐

