TypeScript泛型错误:扁平化3D数组时类型不兼容问题求助
批量Promise处理中的类型兼容问题
背景代码
最初处理批量Promise的逻辑:
const batchedPromises = new Array<any>() for(let i = 0; i < 10; i++) { batchedPromises.push(myPromise(i)) } const settledPromises = await Promise.allSettled(batchedPromises) const fulfilledPromises = settledPromises.filter(({ status }) => status == 'fulfilled').map((p) => (<any>p).value)
为复用逻辑,封装泛型过滤函数onlyFulfilled:
export function onlyFulfilled<T>(settledPromises: Array<PromiseSettledResult<T>>): Array<T> { const fulfilled = (<Array<PromiseFulfilledResult<T>>>(settledPromises.filter(({ status }) => status == 'fulfilled'))) const values = fulfilled.map((v) => v.value) return values }
日常隐式推导泛型的调用逻辑正常:
const settledPromises = await Promise.allSettled(batchedPromises) let fulfilledPromises = onlyFulfilled(settledPromises)
问题场景
当显式指定泛型类型调用后:
let fulfilledPromises = onlyFulfilled<Array<Array<string>>>(settledPromises)
执行数组降维操作时触发类型错误:
Type 'string[][]' is not assignable to type 'string[][][]'. Type 'string[]' is not assignable to type 'string[][]'. Type 'string' is not assignable to type 'string[]'.
原因
显式指定泛型后,fulfilledPromises被强约束为string[][][]类型,而flat()默认降维一级返回string[][],二者类型不兼容导致赋值失败。
解决方案
方案1:新建变量接收降维结果(推荐)
通过新变量明确区分不同维度的数组,代码可读性和类型安全性最高:
let fulfilledPromises = onlyFulfilled<Array<Array<string>>>(settledPromises) const flattenedPromises = fulfilledPromises.flat() // 类型自动推导为string[][]
方案2:用类型联合扩展变量类型
若要复用原变量,可以通过类型联合允许变量兼容两种维度的数组:
let fulfilledPromises: Array<Array<string>> | Array<Array<Array<string>>> = onlyFulfilled<Array<Array<string>>>(settledPromises) fulfilledPromises = fulfilledPromises.flat() // 类型匹配,无报错
方案3:依赖自动类型推导+类型断言
去掉显式泛型指定,让TypeScript自动推导类型,必要时用类型断言临时兼容:
const settledPromises = await Promise.allSettled(batchedPromises) let fulfilledPromises = onlyFulfilled(settledPromises) // 自动推导为Array<Array<Array<string>>> fulfilledPromises = fulfilledPromises.flat() as Array<Array<string>> // 类型断言跳过检查
内容的提问来源于stack exchange,提问作者Riccardo Perego
相关产品推荐
相关产品推荐

