首页 > 解决方案 > 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 操场 上的示例(错误措辞在 ts 操场上有点不同)

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

我对此有两个问题

  1. TS 编译器没有捕捉到这个错误是有原因的吗?我们是否可以更改设置以便它确实捕捉到了这个?在我看来,这是一个可以发现的问题,因为检查代码似乎明显有问题。
  2. 我觉得 TS/JS 没有正确处理这种解构情况很奇怪。我希望 Vaule 变得未定义,而不是导致崩溃。这可能是一个错误吗?

如果Statistics ||去掉了,const [{ Value }] = []则结果如下(ts playground示例

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

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

最后; 我们是否可以使用不同的模式来实现相同的目标,而不会在未来冒这个问题的风险?

标签: typescriptdestructuring

解决方案


目前 TypeScript 无法捕捉到这一点。它将在 4.1 中。

让我们将您的代码重写为:

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

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

“失败”在于没有检查数组实际上是否具有至少一个元素。正如我所说,4.1 将通过正确推断yto的类型StatisticObject | undefined并强制您在访问它之前检查长度来改进这一点。


推荐阅读