问题描述
我们最近在我们的生产系统上发生了一起事件。有很多我们可以而且应该做的事情可以减轻这种情况,但是永远不会减少。
类型+示例代码
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}]
的解构失败。
对此我有两个问题
- TS编译器没有捕获此错误是有原因的吗?我们可以更改设置以便它确实抓住了这一点吗?在我看来,这是一个可捕获的问题,因为检查代码似乎显然是错误的。
- 我觉得奇怪的是,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
的类型并强迫您在访问它之前检查长度来改善这一点。