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

TypeScript递归评论结构中concat方法类型不匹配问题求解

解决TypeScript递归评论结构中的never[]类型错误

问题场景

我正在构建递归评论结构,编写了如下函数:

interface IComment {
  "_id": string;
  "body": string;
  "forum_id": string;
  "parent_comment_id": string;
  "author_name": string;
  "author_id": string;
  "authorPic": string;
  "votes": number;
  "h_voted": number;
  "created_at": string;
  "updated_at": string;
}

const getCommentsWithChildren = (comments: IComment[]) => {
  
  const commentsWithChildren = comments.map((comment) => ({
    ...comment,
    "children": [],// 新增空的子评论数组
  }));
  commentsWithChildren.forEach((childComment) => {
    const { parent_comment_id } = childComment;
    if (parent_comment_id) {
      const parent = commentsWithChildren.find(
        (comment) => parent_comment_id === comment._id
      );
      if (parent !== undefined) {
        parent.children = parent.children.concat(childComment);// 此处报错
      }
    }
  });
  return commentsWithChildren.filter(
    ({ parent_comment_id, body, children }) =>
      parent_comment_id === null && (body !== null || children.length > 0)
  );
};

运行时出现如下错误:

No overload matches this call. Overload 1 of 2, '(...items: ConcatArray<never>[]): never[]', gave the following error.
Argument of type '{ children: never[]; _id: string; body: string; forum_id: string; parent_comment_id: string; author_name: string; author_id: string; authorPic: string; votes: number; h_voted: number; created_at: string; updated_at: string; }' is not assignable to parameter of type 'ConcatArray<never>'.
Type '{ children: never[]; _id: string; body: string; forum_id: string; parent_comment_id: string; author_name: string; author_id: string; authorPic: string; votes: number; h_voted: number; created_at: string; updated_at: string; }' is missing the following properties from type 'ConcatArray<never>': length, join, slice
Overload 2 of 2, '(...items: ConcatArray<never>[]): never[]', gave the following error.
Argument of type '{ children: never[]; _id: string; body: string; forum_id: string; parent_comment_id: string; author_name: string; author_id: string; authorPic: string; votes: number; h_voted: number; created_at: string; updated_at: string; }' is not assignable to parameter of type 'ConcatArray<never>'.

推测是children: []被推断为never[]类型导致的问题,该如何解决?


解决方案

1. 定义递归类型接口(核心)

TypeScript无法自动推断空数组的元素类型,因此需要明确定义带递归children的接口:

interface IComment {
  "_id": string;
  "body": string;
  "forum_id": string;
  "parent_comment_id": string | null; // 修正为允许null,匹配根评论场景
  "author_name": string;
  "author_id": string;
  "authorPic": string;
  "votes": number;
  "h_voted": number;
  "created_at": string;
  "updated_at": string;
}

// 扩展出带子评论的递归接口
interface ICommentWithChildren extends IComment {
  children: ICommentWithChildren[];
}

2. 初始化时指定明确类型

在转换评论数组时,使用定义好的递归接口,避免类型推断错误:

const getCommentsWithChildren = (comments: IComment[]) => {
  // 明确指定数组类型为ICommentWithChildren[]
  const commentsWithChildren: ICommentWithChildren[] = comments.map(comment => ({
    ...comment,
    children: [] as ICommentWithChildren[] // 显式指定children数组类型
  }));

  commentsWithChildren.forEach(childComment => {
    const { parent_comment_id } = childComment;
    if (parent_comment_id) {
      const parent = commentsWithChildren.find(comment => parent_comment_id === comment._id);
      if (parent) {
        // 改用push直接添加元素(更高效)
        parent.children.push(childComment);
        // 若坚持用concat,需将元素放入数组:
        // parent.children = parent.children.concat([childComment]);
      }
    }
  });

  return commentsWithChildren.filter(({ parent_comment_id, body, children }) => 
    parent_comment_id === null && (body !== null || children.length > 0)
  );
};

3. 修正concat的使用(关键细节)

原代码中concat(childComment)是错误用法:concat接收的是数组或多个值,但由于之前的类型推断问题,TypeScript期望传入ConcatArray<never>(即数组)。解决方式有两种:

  • 将单个元素放入数组:concat([childComment])
  • 改用push方法直接添加元素(推荐,因为concat会创建新数组,性能不如push)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 13:15:07