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
相关产品推荐
相关产品推荐

