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

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

关键类型修正说明

  1. 返回值类型:Record<string, (T & { time: string })[]>

    • Record<string, U>:表示键为任意字符串、值为类型U的对象,这里的键就是格式化后的日期字符串。
    • T & { time: string }:交叉类型,代表原对象类型T新增了time字符串属性后的完整类型。
  2. 累加器类型断言:{} 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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 20:57:28