I'm trying to use the --strict
option on tsc
but I ran into the following "weird" case that I don't seem to understand.
If I write:
function testStrict(input: {query?: {[prop: string]: string}}) {
if (input.query) {
Object.keys(input.query).forEach(key => {
input.query[key];
})
}
return input;
}
the compiler complains about:
test.ts(5,9): error TS2532: Object is possibly 'undefined'.
(the offending line is input.query[key];
)
What I don't understand is, I have already checked for undefined with the if guard on the first line of the function if (input.query)
, so why does the compiler think it could possibly be undefined?
I fixed this by adding another identical guard before the object access, like:
function testStrict(input: {query?: {[prop: string]: string}}) {
if (input.query) {
Object.keys(input.query).forEach(key => {
if (input.query) {
input.query[key];
}
})
}
return input;
}
but I don't understand why another identical line would be required.
Because the second access to input.query
happens inside another function the arrow function passed in to forEach
. Flow analysis does not cross function boundaries, so since you are in another function you need to test again.
An alternative to the double test would be to use a local variable, since the type of the variable is locked in on assignment and it will not include the 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;
}