Difference between an undefined value and a missing property in TypeScript

·

2 min read

Cover Image for Difference between an undefined value and a missing property in TypeScript

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 -

Default Profile Picture

Whenever we make any property optional (here src prop), we want to imply the following two cases -

  1. src is passed a string value

     <ProfilePicture 
         src="https://api.dicebear.com/5.x/avataaars/svg?seed=Felix" 
     />
    
  2. src is not passed at all - (missing property)

     //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 ❤️!