Encountered a puzzling issue with TypeScript where it appears that I should be able to recognize that a constant is an array, and then utilize array methods on it. However, TypeScript seems unable to confirm that a value is truly an array even after a direct check.
Given:
type Maybe<T> = T | null | undefined;
type Value = string
| number
| string[]
| number[]
| Maybe<number | string>[];
I can use the .every
array method on a constant by typechecking it in this way:
// This method works well:
const currVal: Maybe<Value> = perhapsSomeValueSomewhere;
if (Array.isArray(currVal)) {
const arr: any[] = currVal;
const isListOfStrings = arr.every((s) => typeof(s) === 'string');
// ... Additional actions here
}
It seems like the above code could be simplified to:
// This method results in an error:
const currVal: Maybe<Value> = perhapsSomeValueSomewhere;
const isListOfStrings = Array.isArray(currVal)
&& currVal.every((s) => typeof(s) === 'string');
// ... Additional actions here
However, this approach leads to an error:
TS2349: Cannot invoke an expression whose type lacks a call signature. Type '((callbackfn: (value: string, index: number, array: string[]) => boolean, thisArg?: any) => boole...' has no compatible call signatures.
It seems like TypeScript may have lost track of the fact that by
&& currVal.every((s) => ...
point, currVal
is indeed some sort of array.
Why does the latter method trigger an error when both logic pieces seem quite similar?