Array.isArray检查不足以完全编译TypeScript中可能的数组值

时间:2019-08-04 02:12:20

标签: typescript

在一个方法中,我有一个可能带有数组值的类型。但是,在访问参数之前,请检查以确保参数不是数组。

this.setState({ cuisine });行上仍然出现以下错误(摘录):

Type 'readonly SelectOption[]' is missing the following properties from type 'SelectOption': value, label

当我将鼠标悬停在错误行上的cuisine上时,由VS Code确定的类型为SelectOption | readonly SelectOption[]

代码如下:

interface SelectOption {
  value: number | string;
  label: string
}

private onCuisineChange(cuisine: ValueType<SelectOption>): void {
    if (Array.isArray(cuisine) && cuisine.length > 1)  {
        throw new Error(`Expected cuisine to be an object, but got ${cuisine}`);
    }

    if (cuisine) {
        this.setState({ cuisine });
    } else {

    }
}


使用TS版本3.5.3

1 个答案:

答案 0 :(得分:2)

TypeScript在此处正确推断类型。除了数组检查外,还有条件&& cuisine.length > 1。这意味着仅当cuisine是其中包含多个元素的数组 时才会引发异常。

如果if是一个空数组或具有单个元素的数组,因此类型为cuisine,则较低的SelectOption | readonly SelectOption[]语句仍然可以执行。

话虽如此,从3.5.1开始,TypeScript#17002(感谢@SeanVieira)仍然对Array.isArray保持开放状态,而没有缩小readonly数组。提供的解决方法是在项目的声明中的某个位置包括重载,以告知打字稿它实际上也应该缩小readonly数组:

  

来自https://stackoverflow.com/a/56249765/10609635

declare global {
    interface ArrayConstructor {
        isArray(arg: ReadonlyArray<any> | any): arg is ReadonlyArray<any>
    }
}