I'm having trouble getting TypeScript to recognise that an optional property of an object is defined.
type OuterKeys = 'a' | 'b';
type Inner = {
value: '';
}
type Outer = Partial<Record<OuterKeys, Inner>>;
const thisGivesError = (key: OuterKeys, outer: Outer) => {
if (outer[key]) {
console.log(outer[key].value);
}
}
Even though I explicitly check if outer[key]
is defined, I'm getting error when trying to access outer[key].value
: Object is possibly 'undefined'
.
How can I work around it? The only way I found is assigning outer[key]
to a variable and having another if
, like below. Is this the only way to go?
const thisWorks = (key: OuterKeys, outer: Outer) => {
const o = outer[key];
if (o) {
console.log(o.value);
}
}
The playground with the code can be found here
Edit: I don't want to use !
operator, as it feels like a workaround - why would I tell TypeScript that this value is set using non-null assertion, if I already checked for its existence with if
? Same for .?
- I already have the if
, so this value for sure exists and is not optional.
CodePudding user response:
At this point, after checking for outer[key]
being truthy, it's safe to go with non-null assertion:
if (outer[key]) {
console.log(outer[key]!.value);
}
Though I don't know how to make TypeScript figure it out on its own.
CodePudding user response:
That's #10530, currently TS doesn't narrow down on indexed access.
CodePudding user response:
Because the inner object which holds the value is never specified to not be undefined. You can fix this by simply adding a question mark.
Ex adding a question mark:
const thisGivesError = (key: OuterKeys, outer: Outer) => {
if (outer[key]) {
console.log(outer[key]?.value);
}
}
CodePudding user response:
You can make use of object?.key
operator. You can learn more about it here.
Your final code will be:
const thisWorks = (key: OuterKeys, outer: Outer) => {
if (outer[key]) {
console.log(outer[key]?.value);
}
}