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;
}
しかし、別の同一の行が必要になる理由がわかりません。
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;
}