web-dev-qa-db-ja.com

タイプスクリプト「エラーTS2532:オブジェクトは未定義のチェックの後でも「未定義」である可能性があります」

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ガードで未定義をすでにチェックしているので、なぜコンパイラは未定義かもしれないと思うのですか?

次のように、オブジェクトアクセスの前に別の同一のガードを追加することでこれを修正しました。

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

しかし、別の同一の行が必要になる理由がわかりません。

14
Martin Sileno

input.queryへの2回目のアクセスは別の関数内で発生するため、矢印関数はforEachに渡されます。フロー分析は関数の境界を越えないため、別の関数にいるため、再度テストする必要があります。

ダブルテストの代わりに、ローカル変数を使用することができます。変数の型は割り当て時にロックされ、undefined typeが含まれないためです。

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