TS 编译器不抱怨可能的未定义对象解构?

TS compiler not complaining about possible undefined object destructuring?

我们的生产系统最近发生了一起事故。我们可以而且应该做很多事情来缓解这种情况,但无论如何都发生了。

键入 + 示例代码

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 playground 上的错误措辞有点不同)

这导致错误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 并强制您在访问它之前检查长度来改进这一点。