异步map+filter转单遍异步reduce报错,如何正确改写?
问题:异步场景下合并map+filter为reduce时的类型错误修复
原可运行代码
const incompleteKYCClaims = await Promise.all( kycPendingProviders.map(async (p) => { const provider = await getProviderOrThrow(p.tin) const isPreviouslyApproved = provider.stripeAccount != undefined if (isPreviouslyApproved) { return } return toProviderRelationshipClaims({ tin: p.tin, role: ProviderUserSubRoles.ky, status: 'KYCInDraft' }) }) ) const incompleteKYCClaimsFiltered = incompleteKYCClaims.filter( (claim) => claim ) as Array<ProviderRelationshipClaims>
尝试的reduce版本(存在错误)
const incompleteKYCClaims = kycPendingProviders.reduce<Array<ProviderRelationshipClaims>>( async (filtered, p) => { const provider = await getProviderOrThrow(p.tin) const isPreviouslyApproved = previouslyApproved.includes(provider.status) if (!isPreviouslyApproved) { filtered.push(toProviderRelationshipClaims({tin: p.tin, role: ProviderUserSubRoles.ky, status: 'KYCInDraft'})) } return filtered }, Promise.resolve([]) as Array<ProviderRelationshipClaims>
报错信息
Argument of type '(filtered: ProviderRelationshipClaims[], p: ProviderRelationship) => Promise<ProviderRelationshipClaims[]>' is not assignable to parameter of type '(previousValue: ProviderRelationshipClaims[], currentValue: ProviderRelationship, currentIndex: number, array: ProviderRelationship[]) => ProviderRelationshipClaims[]'.
修复方案
错误根源在于:reduce回调是async函数,返回值为Promise<Array<ProviderRelationshipClaims>>,但你给reduce指定的泛型是Array<ProviderRelationshipClaims>,且初始值的类型断言错误。另外,每一轮reduce的累积值是Promise,必须先await解析才能操作数组。
修复后的代码如下:
const incompleteKYCClaims = await kycPendingProviders.reduce<Promise<Array<ProviderRelationshipClaims>>>( async (filteredPromise, p) => { // 先解析上一轮的累积Promise,得到当前可操作的数组 const filtered = await filteredPromise; const provider = await getProviderOrThrow(p.tin); // 注意:此处还原原代码的判断逻辑,若你确实需要改用previouslyApproved.includes请自行调整 const isPreviouslyApproved = provider.stripeAccount != undefined; if (!isPreviouslyApproved) { filtered.push(toProviderRelationshipClaims({ tin: p.tin, role: ProviderUserSubRoles.ky, status: 'KYCInDraft' })); } return filtered; }, Promise.resolve([]) // 初始值为已resolve的空数组Promise );
关键修复点:
- 泛型修正:将reduce的泛型指定为
Promise<Array<ProviderRelationshipClaims>>,匹配回调的返回值类型 - 解析累积Promise:在回调开头
await filteredPromise,获取当前可操作的数组 - 初始值修正:直接使用
Promise.resolve([]),无需错误的类型断言 - 逻辑对齐:还原原代码中
isPreviouslyApproved的判断逻辑,避免因逻辑变更引入新问题
内容的提问来源于stack exchange,提问作者Igor Shmukler
相关产品推荐
相关产品推荐

