在此示例中,在if
范围内,p
属性获取对象的类型,但是在箭头函数内部,它是对象或undefined
const o: { p?: { sp?: string } } = { p: {} }
if (o.p) {
const b = ['a'].map(x => {
if (o.p.sp) {
return x
}
})
}
我在内部undefined
处得到了一个可能为'if
'的对象
为什么会这样?如何解决它或打字稿只是坏了?
答案 0 :(得分:1)
这是由于TypeScript中使用strictNullChecks
选项的控制流分析中的限制所致。没有该选项就没有错误。
假设以下简化示例:
const o: { p?: { sp?: string } } = { p: {} }
if (o.p) {
if (o.p.sp) {
// foo
}
}
在这里,TypeScript编译器可以轻松地推断出自执行o.p
以来,o
和if (o.p)
均未更改。结果,它可以正常工作而没有任何错误。但是,一旦您引入更多的功能(例如函数调用),就会出现问题,这些功能可能会对o
产生副作用。
有关详细信息,请参见Trade-offs in Control Flow Analysis。可能有助于理解此问题的注释示例之一是此代码:
if (token === SyntaxKind.ExportKeyword) { nextToken(); if (token === SyntaxKind.DefaultKeyword) { // We have "export default" } ... }
乍看之下,嵌套if
子句是没有意义的,TypeScript会警告您。但是,nextToken()
可能实际上会更改token
,因此代码可能有意义。但是,对于编译器而言,很难真正正确地理解和解释这种情况。
通过将o.p.sp
替换为o.p!.sp
或o.p && o.p.sp
,可以避免代码中的错误消息。