I've seen a few similar questions but none had the same issue.
I am being confused around Object that is possibly undefined error from TypeScript.
interface Props {
item?: SomeItem;
}
export const Element = (props: Props) => {
if (props.item === undefined) {
return null;
}
const offer = offers.find((offer) => offer.id === props.item.offer_id);
return <div>{props.item.getPayoutPlaceholder()}</div>;
};
The error is
TS18048: 'props.item' is possibly 'undefined'. const offer = offers.find((offer) => offer.id === this.item.offer_id);
It shows ONLY in the find
line. The last one (return
) doesn't suffer from this.
If I assign the props.item
to a constant and use it, It stops
const item = props.item;
if (item === undefined) {
return null;
}
const offer = offers.find((offer) => offer.id === item.offer_id);
I get that it could change after the if
by some asynchronous code. But what makes me really confused is the fact that it doesn't show the same error in return
statement. What could be the reason for this?
This is because props.item.offer_id
is in a callback, and so TS cannot be sure that props.item
has not changed between the time you check it and the time the callback is called. As you noted, you could get around it by defining a constant variable:
const item = props.item;
It should also be noted that destructuring also works:
export const Element = ({ item }: Props) => {
but notice that changing const
to let
makes the original error surface again:
let item = props.item;
and that's because now TS is not sure that it hasn't changed, like before (since let
is mutable and can be reassigned).
The usage of props.item.offer_id
works in the return
statement because it isn't in any sort of context that can have delayed execution. As an example of this, in the following code, TS is smart enough to see that this function expression will be immediately invoked and thus it must be synchronous:
// OK, even though it's in another function
(() => props.item.offer_id)();
Anyways, regardless of why TS behaves the way it does here, I suggest you use destructuring directly from the parameter list. It's clean, widely used, and solves this issue straight away without needing to declare extra constant variables.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With