0

我在使用 TypeScript 时遇到了一个奇怪的问题,似乎我应该能够推断出一个常量是一个数组,并且有了这个知识就可以调用数组方法。但是,即使经过显式检查,TypeScript 显然也无法确定一个值是否真的是一个数组。

鉴于:

type Maybe<T> = T | null | undefined;

type Value = string
  | number
  | string[]
  | number[]
  | Maybe<number | string>[];

.every如果我因此对常量进行类型检查,我可以在常量上调用数组方法:

// This approach works fine:
const currVal: Maybe<Value> = perhapsSomeValueSomewhere;

if (Array.isArray(currVal)) {
  const arr: any[] = currVal;
  const isListOfStrings = arr.every((s) => typeof(s) === 'string');

  // ... Do other stuff here
}

我觉得应该遵循以上可以简化为:

// This approach results in an error:
const currVal: Maybe<Value> = perhapsSomeValueSomewhere;
const isListOfStrings = Array.isArray(currVal)
  && currVal.every((s) => typeof(s) === 'string');

// ... Do other stuff here

但是,这种方法会导致错误:

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.

我只能假设这意味着,在此过程中,TypeScript 已经失去了上下文,&& currVal.every((s) => ...此时,currVal它确实是某种数组。

当这两位逻辑看起来相当可比时,为什么后者会导致错误?

4

1 回答 1

1

在第一种情况下,您通过将 currVal 分配给 any[] 来进行隐式类型转换,在第二种情况下,您没有将类型转换为数组类型。您可以使用以下显式强制转换来使其工作。

const isListOfStrings = Array.isArray(currVal) && (<Array<any>>currVal).every((s) => typeof (s) === 'string');
于 2018-12-04T00:45:23.540 回答