If I have code roughly like this:
const obj: Record<string, SomeType>;
if ("key" in obj) {
const val: SomeType = obj["key"];
void val;
}
the TypeScript compiler doesn't give me any grief about the type of val.
Likewise if I write code like:
const val = obj["key"];
if (val) {
const val2: SomeType = val;
void val2;
}
the TypeScript compiler knows that val/val2 can't be | undefined inside the check.
But if I write code like:
let k = "key";
if (obj[k]) {
const val: SomeType = obj[k];
void val;
}
then TypeScript complains that val: Sometype could still be | undefined.
Even if I use a const in a situation somewhat similar to the last it stays unhappy:
(["a", "b", "c"]).forEach(_k => {
const k = _k;
if (obj[k]) {
const val: SomeType = obj[k];
// ^^^ VSCode still thinks it could be `| undefined`!
}
});
Why is this?
I'm not that good at reasoning with types, but in your third block, changing
kto aconstmakes the types work:And this doesn't fix your issue, but you can assert that an array is
constinline. The fourth code block I can only make typecheck by adding an intermediate step:Hope this helps you get on with whatever you're doing, but hopefully someone smarter with typescript reasoning can explain exactly what's going on.
n.b. I changed your
SomeTypetostringto make it easier to work with in vscode.