TS编译器没有抱怨可能的未定义对象销毁?

问题描述

我们最近在我们的生产系统上发生了一起事件。有很多我们可以而且应该做的事情可以减轻这种情况,但是永远不会减少。

类型+示例代码

interface StatisticObject {
    Value: number,someData: string
}
function somePromise(): Promise<{data: {Statistics: StatisticObject[] | undefined}}> {
    return Promise.resolve({data: {Statistics: undefined}})
}

我们在生产中使用了此代码

somePromise()
.then(({ data: { Statistics } }) => {
    const [{ Value }] = Statistics || []

    return Value || 0
})

ts playground上的示例(ts操场上的措辞有些不同)

这导致错误Cannot read property 'Value' of undefined,因为Statistics对象未定义,导致||语句被触发。该数组为空,因此const [{Value}]的解构失败。

对此我有两个问题

  1. TS编译器没有捕获此错误是有原因的吗?我们可以更改设置以便它确实抓住了这一点吗?在我看来,这是一个可捕获的问题,因为检查代码似乎显然是错误的。
  2. 我觉得奇怪的是,TS / JS无法正确处理这种销毁情况。我希望Vaule变得不确定,不会导致崩溃。这可能是错误吗?

如果删除Statistics ||,结果为const [{ Value }] = [],则结果如下(ts playground example

Tuple type '[]' of length '0' has no element at index '0'.(2493)
Property 'Value' does not exist on type 'undefined'.(2339)

即使是前面的Statistics ||,这也是我希望看到的错误,因为它可能是undefined

最后;我们可以使用其他模式来实现相同的目标,而不必再冒这个问题的风险吗?

解决方法

目前,TypeScript不能捕捉到它。它将在4.1。

让我们将代码重写为此:

const x = Statistics || []
const y = x[0]        
return y.Value || 0

x的推断类型为StatisticObject[]y的推断类型是什么?它是StatisticObject,但实际上应该是StatisticObject | undefined,因为只有在运行时我们才能知道该数组不为空。

“失败”是不检查数组实际上是否至少有一个元素。 就像我说的那样,4.1将通过正确地将y的类型推断为StatisticObject | undefined的类型并强迫您在访问它之前检查长度来改善这一点。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...