Using Discriminated Unions to Create Flexible Component Props in React
Here's the starting point of our Modal
component:
type ModalProps = {
variant: "no-title" | "title"
title?: string
}
export const Modal = (props: ModalProps) => {
if (props.variant === "no-title") {
return <div>No title</div>
} else {
return <div>Title: {props.title
Transcript
00:00 So the best way to solve this is with a discriminated union. And the way you can think about that is you can think about the various different states that you want your modal props to be in. Now we really have two different states here. We have a state with no title and a state with a title. Currently this is very, very mushy.
00:19 It's just letting us pass in whatever we want to. So I'm actually going to remove that and then just make this the no title variance here. Now props.title is erroring because it doesn't exist in type of modal props and it's erroring down here too. So we want to now add the different states, the different possibility into this.
00:38 So we can do that with this or symbol here, which is the union type, and we can add a new title. So variant title. And let's now add in title string here. Now what this does is it means that we can either hit this branch of the union or this branch here.
00:57 And this means that if we try to, let's say, just code this up from scratch, then first of all it's going to yell at us because it's like not assignable to type intrinsic attributes and modal props. Very helpful error. But the thing we're missing here is a variant. And so we can either pass in no title or title. So we get this here.
01:13 If we pass in title, then it's going to yell at us again because title is missing in variant title. So now let's stick that in. Beautiful. And now we're forced to pass our title. And if we pass no title, then it's going to error at us because we've not, well, because we've passed in the title there.
01:32 Title title title title title, etc. So this is a really powerful pattern and you should probably be using it more often in your React apps. In the next few exercises, we're going to dive deeper into this and look more at its
01:43 possibilities.