Check out a free preview of the full React and TypeScript course:
The "Limiting Props" Lesson is part of the full, React and TypeScript course featured in this preview video. Here's what you'd learn in this lesson:

Steve demonstrates how to limit the props a component can take base on the state of other props. Limiting prop intake can help avoid errors with multiple optional props and safeguard the code against incorrect props being passed in.

Get Unlimited Access Now

Transcript from the "Limiting Props" Lesson

[00:00:00]
>> Then our next kind of like exercise here, we are going to look at some of the more sophisticated seems really some more advanced, if you will, component patterns. That you might again the thing I'll say is like definitely making your opponent library but like also if you're just working in a large code base because yeah.

[00:00:26] So this is a common pattern now we have a design system and in our design system, you have different variants of a button, you have a primary button, a secondary button, a destructive button, a disabled button, small buttons, big buttons, all sorts of buttons. And though the way that we do it is it's actually more like this like button and then variant is primary.

[00:00:56] But you can have a button that is both primary and secondary, but you can have like a primary disabled button and stuff along those lines. So this is one way to do it with just having a string you can use a union type. What I would love to do is have a syntax more like this where I can kind of just pass any other types of buttons indirectly as a prop.

[00:01:23] In case, you've probably seen this syntax before, but if you haven't in react, any prop is passed in without an equal sign an argument is just true. It's just a Boolean and it's true. So you can see that we've got this type up here, where we've got the children.

[00:01:39] And in this case, we know that react node can be a child I'm making it so that since it's a button, it is only a string. So I'm again, using my types to enforce the intention of my code. But I've got three optional prompts. So there's nothing stopping me right now.

[00:01:55] They're saying that a button is both primary and secondary. And that's not great because it's like a, in this case, whatever order they're in here like wins because that's the way the class names are put on there. Like that's not great. And so I want to make it so that like if somebody accidentally does that TypeScript warns them at compile time, and we don't ship it to production.

[00:02:20] Because that would just be one of those things where it's like, you might have a Cypress test that's lucky enough to catch it, but probably is just a booboo that you didn't mean to do and you will find a customer found defect around it. So what we're going to try to do is get a little advance with our types and see if we can create a system where you can pass in any given one of those properties, but not more than one.

[00:02:52] And this will be somewhat similar if you remember when we were talking the reducers. And we said okay for increment and decrement I don't want a payload. But for set, I do want a payload with a new value. This is somewhat similar to what we did there as well.

[00:03:10] And so what we're going to do is create some new types here. So we've got button props and button props are going to be the props that are common to all of the buttons. And so we're going to remove some stuff, we're going to basically end up removing these three, but we'll start out by just making our new types.

[00:03:29] And so type primary button props, Is going to be everything in button props, Along with primary being a Boolean. Right, and you can see how the story goes. The secondary button props Would be Destructive button props will be everything shared in the button prompts and then destructive is a Boolean.

[00:04:16] So let's look at what we have here. This is kind of interesting up, hold on. Let's actually remove this part here first. So you can see that it's button props and prime minister bullying so on and so forth, right? In this case, it will be children and primary, children and secondary, children and destructive, but not more than one.

[00:04:39] Before we had options, it like the either undefined or they're set. Here we're saying we have three different types which is simply the children and maybe, yes, Prime Minister, I thought it was a V for a second there. So it's now three different types, where can be any given one of those, right?

[00:04:57] But not all of them, and we can get a little bit better because now we've just an optional if any of them. TypeScript has a type called never. And it's like, if optional is like maybe you hand it to me. Never is absolutely not. Should this ever be set, no matter what.

[00:05:18] And so if you think about this, we could do something kind of interesting here as well. Where we say all right, we're gonna say its primary, but then secondary should never be that destructive, Never as well. So we can do that as well. Again adding an additional kind of safety there.

[00:05:52] Here we'll just change this one to primary. And we'll change this one here to primary. Cool, so we've got that all in place. And so now we can kind of change our button props a little bit as well. And so we're going to do here is we'll go ahead and we'll say alright, because button props is now just children.

[00:06:23] So you can see that all of these are angry about primary, secondary and destructive. So none of that is working the way that we want it to. So what we need to do is say, listen, you can be any of these three types. We're cool with any of them.

[00:06:34] And you can see that the nice part is that they kind of don't overlap. So we can go ahead and we'll say that, okay, all three of these are false and we'll say it's button props. We can actually probably just get away with saying, hey let's try it out.

[00:06:48] We'll say, this is a union of PrimaryButtonProps or SecondaryButtonProps or DestructiveButtonProps, cool. Now you can see everything works but if I try to pass in secondary, Button is now angry with me. You can pass in anyone but you can't pass into, because it'll match any one of these types but you can see that these other types here don't allow secondary or destructive either, right?

[00:07:33] And so we can now have any given one of them I think you can probably even remove these I like these because they actually make it very clear. I'm pretty sure you're moving to find out together. If not, I'll quickly walk that back. So we do need the never on those otherwise it will try to match, so put that back.

[00:07:52] So yeah, we have these types which are effectively primary, secondary and destructive. You cannot put more than one because any given type discludes the other ones. So yeah, is an effective way to just add more safety to how you intend your components to be used. And useful like, do you need to do it all the time?

[00:08:15] No. But if you know that you're building a component library used by other teams incredibly useful, or if you just know that again, over time, the intention of that code, all those great ideas that you had. Start to slip away a little bit like it. There's two developers, you have to worry.

[00:08:31] The most important valve in the world is you six months from now, who doesn't know what you meant when you wrote that code originally. So you are basically trying to do a favor to future you in this case. Again, the most important developer in the world.