即使在未定义检查之后,打字稿“错误 TS2532:对象可能是‘未定义’”
Posted
技术标签:
【中文标题】即使在未定义检查之后,打字稿“错误 TS2532:对象可能是‘未定义’”【英文标题】:Typescript "error TS2532: Object is possibly 'undefined'" even after undefined check 【发布时间】:2018-09-11 15:23:01 【问题描述】:我正在尝试在tsc
上使用--strict
选项,但遇到了以下我似乎无法理解的“奇怪”案例。
如果我写:
function testStrict(input: query?: [prop: string]: string)
if (input.query)
Object.keys(input.query).forEach(key =>
input.query[key];
)
return input;
编译器抱怨:
test.ts(5,9):错误 TS2532:对象可能是“未定义”。
(违规行是input.query[key];
)
我不明白的是,我已经在函数if (input.query)
的第一行使用 if 守卫检查了 undefined,所以 为什么编译器认为它可能是 undefined?
我通过在对象访问之前添加另一个相同的保护来解决此问题,例如:
function testStrict(input: query?: [prop: string]: string)
if (input.query)
Object.keys(input.query).forEach(key =>
if (input.query)
input.query[key];
)
return input;
但我不明白为什么需要另一条相同的行。
【问题讨论】:
虽然这对于同步运行的forEach
没有意义,但在一般情况下,当我们考虑回调函数时,它确实有意义。如果您传递的那个函数是一个回调函数,那么它可能直到将来某个时候才会被调用,到那时input
对象可能已经改变(input.query
可能已经变得未定义)。所以 TS2532 在处理回调时帮助我们免于被枪杀。 Titian 的解决方案不仅满足 TypeScript,而且还防止了特定错误的发生。 (通过保留对原始 query
对象的引用。)
【参考方案1】:
因为对input.query
的第二次访问发生在另一个函数内部,所以箭头函数传入forEach
。流分析不跨越函数边界,因此由于您处于另一个函数中,因此您需要再次测试。
双重测试的替代方法是使用局部变量,因为变量的类型在赋值时被锁定,并且不包括 undefined
类型:
function testStrict(input: query?: [prop: string]: string )
if (input.query)
const query = input.query;
Object.keys(input.query).forEach(key =>
query[key];
)
return input;
【讨论】:
如果您将let query
替换为const query
,效果会更好以上是关于即使在未定义检查之后,打字稿“错误 TS2532:对象可能是‘未定义’”的主要内容,如果未能解决你的问题,请参考以下文章