首页 > 解决方案 > 无法使用打字稿联合类型调用 Array.every()

问题描述

下面的代码在使用时会抛出错误Array.every()

// In my code, data it would be assigned from an API response;
let data: string[] | string[][] = []; 

// Need to use every() and some() for checking
let isChecked = false;

// Check if the type is string[][], got error with every()
if (data.length && data[0] instanceof Array) {
    isChecked = data.every(...);
}

// Check if the type is string[], no error with some()
if (data.length && typeof data[0] === 'string') {
    isChecked = data.some(...);
}

打字稿将在以下位置显示此错误every()

Each member of the union type 
'{ <S extends string>(predicate: (value: string, index: number, array: string[]) => value is S, thisArg?: any): this is S[]; 
(predicate: (value: string, index: number, array: string[]) => unknown, thisArg?: any): boolean; } | { ...; }' 
has signatures, but none of those signatures are compatible with each other

我该如何克服这个错误。这是一个打字稿游乐场示例

标签: typescripttypestype-conversionunion-types

解决方案


let a: string[] | string[][] = [];


const isArrOfArr = (arg: any): arg is string[][] => Array.isArray(arg) && Array.isArray(arg[0])

const isArrOfArr_super_safe = (arg: any): arg is string[][] => Array.isArray(arg) && arg.every(Array.isArray)


if (isArrOfArr(a)) {
    let b = a.every(elem => elem) // ok
}

TS 不将data[0] instanceof Array其视为第一个元素的类型保护,因为默认情况下数组是可变的。

您可以为此目的使用自己的 typeguard


推荐阅读