如何通过Array.some()实现TypeScript联合类型数组的类型收窄?
解决TypeScript数组类型收窄问题
在你的场景中,TypeScript无法通过arr.some(isA)的反向逻辑(即数组中不存在A类型元素)自动将(A|B)[]收窄为B[],这是因为some()方法的类型守卫只能推断数组存在符合条件的元素,无法反向推导“所有元素都不符合”的数组整体类型。
以下是两种可行的实现方案:
方案一:直接用every()判断所有元素为B
利用Array.every()结合元素类型守卫的特性——当every(isB)返回true时,TypeScript会自动将数组类型收窄为B[]:
function isA(x: any): x is A; function isB(x: any): x is B; if (!arr.every(isB)) return; arr; // 此时类型为B[]
方案二:自定义数组级类型守卫
如果需要保留“存在A则返回”的逻辑,可以自定义一个类型守卫函数,专门断言数组所有元素都是B:
function isA(x: any): x is A; function isB(x: any): x is B; // 自定义类型守卫:判断数组所有元素均为B function isAllB(arr: (A|B)[]): arr is B[] { return !arr.some(isA); } if (arr.some(isA)) return; // 手动调用类型守卫完成类型收窄 if (!isAllB(arr)) return; arr; // 此时类型为B[]
或者更简洁地整合逻辑:
function isA(x: any): x is A; function isB(x: any): x is B; function isAllB(arr: (A|B)[]): arr is B[] { return !arr.some(isA); } if (!isAllB(arr)) return; arr; // 此时类型为B[]
内容的提问来源于stack exchange,提问作者Lucien950
相关产品推荐
相关产品推荐

