The problem is that the compiler doesn’t know how to do narrowing on an object property like IceCreams[item]
where you are indexing with a key whose type isn’t known to be a specific literal type. TypeScript is only following the type of the index, not the identity. And the type of item
is string
. If you have item1
and item2
, both of type string
, then checking IceCreams[item1]
wouldn’t let you conclude anything about IceCreams[item2]
, right? And since TypeScript can’t tell the difference between item1
vs item2
or item
vs item
, it can’t narrow. This is a known limitation of TypeScript reported at microsoft/TypeScript#10530. Maybe someday it will be addressed. But for now, there’s an easy workaround:
Just copy the value into a new variable, so that the problematic indexing occurs only once:
iceCreamKeys.forEach(item => {
const x = IceCreams[item];
if (x.natural) {
console.log(x.naturalComponent) // okay
}
})