打字稿"错误TS2532:对象可能是'未定义的'"即使在未定义的检查之后

Mar*_*eno 15 typing typescript tsc

我正在尝试使用该--strict选项,tsc但我遇到了以下"奇怪"的情况,我似乎并不理解.

如果我写:

function testStrict(input: {query?: {[prop: string]: string}}) {
  if (input.query) {
    Object.keys(input.query).forEach(key => {
      input.query[key];
    })
  }
  return input;
}
Run Code Online (Sandbox Code Playgroud)

编译器抱怨:

test.ts(5,9):错误TS2532:对象可能是"未定义的".

(违规行是input.query[key];)

我不明白的是,我已经在函数的第一行用if guard检查了undefined if (input.query),为什么编译器认为它可能是未定义的?

我通过在对象访问之前添加另一个相同的防护来修复此问题,例如:

function testStrict(input: {query?: {[prop: string]: string}}) {
  if (input.query) {
    Object.keys(input.query).forEach(key => {
      if (input.query) {
        input.query[key];
      }
    })
  }
  return input;
}
Run Code Online (Sandbox Code Playgroud)

但我不明白为什么需要另一条相同的线.

Tit*_*mir 15

因为第二次访问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;
}
Run Code Online (Sandbox Code Playgroud)