TypeScript数组reduce转换时添加time属性的类型定义问题
修正TypeScript泛型函数的类型定义问题
你的核心问题是返回值类型和累加器类型的声明错误:原类型用[key in keyof T]会把输入对象T的属性作为结果对象的键,但实际结果的键是格式化后的日期字符串;同时数组元素应该是原对象T新增time属性后的类型,而非数组本身和time交叉。
修正后的完整代码
import dayjs from 'dayjs'; export function getObjectOfArrayByKey<T, K extends keyof T>( data: T[], key: K, timeFormat: string, dateFormat: string, ): Record<string, (T & { time: string })[]> { return data.reduce((acc, item) => { // 解析时间并生成格式化后的日期、时间字符串 const time = dayjs(item[key]).format(timeFormat); const date = dayjs(item[key]).format(dateFormat); // 生成带time属性的新对象 const itemWithTime = { ...item, time, }; // 初始化对应日期的数组(如果不存在) acc[date] = acc[date] || []; // 将新对象加入数组 acc[date].push(itemWithTime); return acc; }, {} as Record<string, (T & { time: string })[]>); }
关键类型修正说明
返回值类型:
Record<string, (T & { time: string })[]>Record<string, U>:表示键为任意字符串、值为类型U的对象,这里的键就是格式化后的日期字符串。T & { time: string }:交叉类型,代表原对象类型T新增了time字符串属性后的完整类型。
累加器类型断言:
{} as Record<string, (T & { time: string })[]>- 和返回值类型保持一致,确保TypeScript能正确推导累加器的结构,避免类型报错。
可选优化:添加时间类型约束
如果需要确保传入的key对应的属性是dayjs可解析的时间类型(字符串、Date、数字),可以给泛型K添加额外约束:
export function getObjectOfArrayByKey<T, K extends keyof T>( data: T[], key: K, timeFormat: string, dateFormat: string, ): Record<string, (T & { time: string })[]> { return data.reduce((acc, item) => { // 断言item[key]为dayjs可解析的类型 const timeVal = item[key] as unknown as string | number | Date; const time = dayjs(timeVal).format(timeFormat); const date = dayjs(timeVal).format(dateFormat); const itemWithTime = { ...item, time, }; acc[date] = acc[date] || []; acc[date].push(itemWithTime); return acc; }, {} as Record<string, (T & { time: string })[]>); }
内容的提问来源于stack exchange,提问作者Irina Mysko
相关产品推荐
相关产品推荐

