typescript - 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}]
解构失败。
我对此有两个问题
- TS 编译器没有捕捉到这个错误是有原因的吗?我们是否可以更改设置以便它确实捕捉到了这个?在我看来,这是一个可以发现的问题,因为检查代码似乎明显有问题。
- 我觉得 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
.
最后; 我们是否可以使用不同的模式来实现相同的目标,而不会在未来冒这个问题的风险?
解决方案
目前 TypeScript 无法捕捉到这一点。它将在 4.1 中。
让我们将您的代码重写为:
const x = Statistics || []
const y = x[0]
return y.Value || 0
的推断类型x
是StatisticObject[]
。推断的类型是y
什么?是的,StatisticObject
但实际上应该是StatisticObject | undefined
,因为只有在运行时我们才能知道数组不是空的。
“失败”在于没有检查数组实际上是否具有至少一个元素。正如我所说,4.1 将通过正确推断y
to的类型StatisticObject | undefined
并强制您在访问它之前检查长度来改进这一点。
推荐阅读
- lua - 游戏鼠标上的 LUA 脚本在 Origin 软件中不起作用
- swift - SpriteKit:SKPhysicsJointPin 允许节点穿透节点链
- python - 使用缩放监视器捕获 Python 应用程序
- firebase - 第二个 Firebase 项目无法访问第一个项目 Firestore
- javascript - JS:如何移除动画而不是仅仅停止它们?
- version-control - 我在哪里可以找到 Erlang/OTP R14B05 的副本?
- flutter - getter 'hasFocus' 在 null 上被调用
- html - CSS 媒体查询不能在移动设备上运行,但可以在桌面上运行
- linux - “错误:EACCES:权限被拒绝” - 在 AWS EC2 实例上运行 Meteor 应用程序 (OHIF)
- python - from django.db.models import Q, Count, F, JSONField ImportError: cannot import name 'JSONField'