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

如何将TypeScript中含两种类型的数组过滤为单一Comment类型数组?

解决snoowrap getReports返回类型收窄问题

这个问题我之前也碰到过——snoowrap的TypeScript类型定义在这里确实有点小坑,明明指定了only: 'comments',返回的类型还是Submission | Comment的联合数组。不过用TypeScript的类型守卫就能完美解决类型收窄的问题,具体做法如下:

1. 编写类型守卫函数

首先我们需要一个函数来明确判断某个元素是不是Comment类型。利用Reddit API原生的kind字段最可靠:评论的kind是t1,帖子的kind是t3,snoowrap会保留这个属性。

import snoowrap from 'snoowrap';

// 类型守卫函数:判断传入项是否为Comment类型
function isComment(item: snoowrap.Submission | snoowrap.Comment): item is snoowrap.Comment {
  // 断言为Comment后检查kind字段
  return (item as snoowrap.Comment).kind === 't1';
}

2. 过滤数组并收窄类型

调用getReports后,用这个类型守卫函数过滤数组,TypeScript会自动推断出过滤后的数组是纯Comment[]类型:

async function fetchReportedComments(subredditName: string) {
  // 假设你已经初始化好了snoowrap实例r
  const subreddit = await r.getSubreddit(subredditName);
  
  // 虽然传了only: 'comments',但返回类型还是联合数组
  const allReports = await subreddit.getReports({ only: 'comments' });
  
  // 过滤后得到纯Comment数组,类型自动收窄
  const reportedComments = allReports.filter(isComment);
  
  return reportedComments; // 返回类型为Promise<snoowrap.Comment[]>
}

简化写法:内联类型守卫

如果不想单独写函数,也可以把类型守卫直接写在filter回调里:

const reportedComments = allReports.filter(
  (item): item is snoowrap.Comment => item.kind === 't1'
);

原理是item is snoowrap.Comment这个类型谓词告诉TypeScript:当回调返回true时,当前的item就是Comment类型,因此过滤后的数组类型会被正确推断为Comment[]。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 07:24:22