Conditional types for props using TypeScript and React

Everaldo Junior
3 min readJan 17, 2022

Part One: Scenario and Final Result

Let’s imagine a scenario where we have an Avatar component, that shows an image or the user name initials, depending on the type selected:
“IMAGE” | “INITIALS”

When we select the “IMAGE” type on the Avatar component, it should have a required prop “url”

When we select the “INITIALS” type on the Avatar component, it should have a required prop “initials”

This is our expected code:

And this is our expected result:

With “url” and “initials” props being required depending on the type, like the images below after we comment the required prop

Part Two: Types and Interfaces

First, let's create a index.ts file and a “types” folder under “src”

Inside index.ts file we are going to define an Enum with the possible components (Avatar with image and Avatar with initials)so we can use it to help us later.

Now, we’re going to define the types of “Avatar with image” and “Avatar with initials” components using the enum that we created before. Note that we’re defining the required props and the type of each component here.

Now, comes the tricky part, we are going to create an interface and name it “AllAvatarProps” with the combination of AvatarWithImageProps and AvatarWithInitialsProps, but defining required props as optional and defining props that both of them have as required

We also need to extend AvatarWithInitialsProps and AvatarWithImageProps with this AllAvatarProps interface, so the magic can happen.

And the last thing we need to do is export a type with de Union of AvatarWithImageProps and AvatarWithInitalsProps, and name it “SelectedModeProps”

Parth Three: Components

Let’s implement the components with their interfaces

First, I’m going to create a “components” folder under src

Now, I’m going to create the AvatarWithImage component under the “components” folder with the code below.

Note that we need to add AllAvatarProps as AvatarWithImage Interface

Now we’re going to do the same thing with AvatarWithInitials component:

Ok, now come’s another tricky part, we’re going to implement a third component that will handle which component and which required props are selected as we saw at the beginning of this tutorial.

Now we can implement the layout from the beginning of the tutorial:

Achieving the expected result:

With conditional props typing:

Github source

Do you know another way to achieve this result? Let me know in the comments :)

--

--