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 -
src
is passed a string value<ProfilePicture src="https://api.dicebear.com/5.x/avataaars/svg?seed=Felix" />
src
is 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 ❤️!