Difference between an undefined value and a missing property in TypeScript
2 min read

There is one serious issue with the default behavior of the typescript compiler w.r.t optional types.
To properly understand the difference between an undefined value and a missing property, let's take an example -
Let's say we have the following ProfilePicture component -
type Props = {
src?: string;
};
export const ProfilePicture = (props: Props): JSX.Element => {
const defaultProps = {
alt: "Profile Picture",
src: `https://api.dicebear.com/5.x/miniavs/svg`
};
return <img {...defaultProps} {...props} />;
};
Here, we are expecting an optional prop src.
If src is not passed, we are rendering the default profile picture -

Whenever we make any property optional (here src prop), we want to imply the following two cases -
srcis passed a string value<ProfilePicture src="https://api.dicebear.com/5.x/avataaars/svg?seed=Felix" />srcis not passed at all - (missingproperty)//default profile picture will be rendered in this case <ProfilePicture />
However, TypeScript, by default, doesn't differentiate between undefined value and a missing property.
This means that it won't complain even if we accidentally passed an undefined value to src-
// ❌ This breaks our application ❌
<ProfilePicture src={undefined} />
This will override our default value of src which will, in turn, break our application -

To prevent such issues, TypeScript 4.4 introduced a new flag exactOptionalPropertyTypes which specifies that optional property types should be interpreted exactly as written, meaning that | undefined is not added to the type.
Now, with exactOptionalPropertyTypes flag enabled, passing an undefined value will throw an error -
// ❌ Type 'undefined' is not assignable to type 'string'.
<ProfilePicture src={undefined} />
Thanks for reading ❤️!