React and TypeScript, v2

Typing Component Children Exercise

Steve Kinney

Steve Kinney

React and TypeScript, v2

Check out a free preview of the full React and TypeScript, v2 course

The "Typing Component Children Exercise" Lesson is part of the full, React and TypeScript, v2 course featured in this preview video. Here's what you'd learn in this lesson:

Students are instructed to type non-primitive objects like React components. These include JSX elements and React nodes/children.


Transcript from the "Typing Component Children Exercise" Lesson

>> So props are fun. There is one other kind of situation that we didn't really talk about, which I'm gonna challenge you with. Which is, so we got props, some of them could be static values, some of them could be objects or arrays, and we'll see those over time.

We saw what to do with an event handler. There's one more other common prop, right? I have a list of all the other props you could ever see as well, but there's one that you might end up with, which is what do you do about children? That is usually the first TypeScript going great in React, I love this.

This is about never writing JavaScript again, and the first time you need to type, it'd be like, that's another React component. You're like, I think I'm just gonna write JavaScript. So what I have for you is kind of a little playground, and in here we've got, open this in Safari in a second, or it's a repo to the enclone.

My security settings are turning off syntax, highlighting in edge. But we have one where it's one child, it's a string cuz children of an HTML element could be a string, nothing, another HTML element, right, a bunch of stuff, right, and so we need to kind of figure that out.

And so right now this isn't any, and your job is, here are a bunch of options, I thought seemed plausible looking at reacts types. What I would challenge you to do is try these out and see where the red squigglys come to haunt you, right? And when you have the wrong answer, a red squiggly will let you know, cuz most of the cases are covered in here.

And we will figure out what the correct type of a given child component should be. All right, spend five minutes, and we will reconvene. We'll look at the the answer sheet in a second. But let's try these all out and kinda see what just our editor tells us, right?

Let's try JSX element. And you can see that I get yelled at for anything that has more than one element in it, right. That makes sense. But we saw before, okay, JSX element was my first go-to, because before we hovered over name badge, we saw JSX element, right, which is true except it could be more than one.

And so the syntax for an array, depending on where your cursor is. And this blows up in a different way because it's like, cool, it can be more than one JSX element, which makes this box very happy. But you know what's not a JSX element? A string, so you could continue to play this game forever.

You say, or a string, and I think if it has two strings at that point you get yelled at, but there's really no intersection there. These two at the bottom, I'm not even gonna waste your time with. They're fake answers. Those are actually utility methods built into React for mapping over children, those aren't even types.

The correct answer here is React.React(Node). And I will show you a fun thing to make you never have to really think about this again. You pass it in, everything is happy and wonderful and good in the world. The other thing that you can do, so other than this, this doesn't really take any props other than children.

So what I can do in this case is there's actually one built into React, Called props with children, which uses the syntax for taking it generic and says, this would be the rest of your props. This would be name badge props or greeting props or whatever. And it adds, hey, this could have children that are either React node or undefined, right.

And you can kind of use that as built in there andyou just have fun with that. You'll get like that typing for you as well. But the thing I would love to be able to do is also, I have this idea of a style prop, right, cuz I do get cool autocomplete here as well.

If you've learned anything about me right now,it's that I like especially all this stuf, having it filled in for me. And a lot of times people will just be string, so I can still go rogue here, but I can put these properties in. And maybe I want my wrapper component to also be able to take a style element that it passes through, but well, I don't really just want to say it's an object or anything along those lines.

And again, we can kind of figure out by introspecting that. React does have this type, and at any point if you get interested in these you can always Command click and go through and actually see the types. It's an experience that everyone should go through, but over time it's kind of like seeing the matrix.

But we can take this and we can basically say that, okay, we do wanna actually take a style tag. And this is kind of useful too, depending on how complicated your component is. If you wanna pass different styles for the outer component and stuff like that, you can actually then be able to use this property in multiple places, right?

And now, this style will have all the same typing that we eventually pass through to the child component in this case, so we can actually say, Spread the rest of the properties in there, not if we don't write regular JavaScript. Cool, and so I can pass those in as well and because they're the same type, TypeScript is all okay with it.

It's like, if you're guaranteeing that this style object is okay, then I will let you use it in React component where it's expecting that style object as well, and both of those just kind of work. So the kind of answer again, which I have written out here, Is we do want React.React(node).

The rest of these don't really work the way we think they do. And so sometimes, there is a little nuance there. But the props with children is usually your answer, cuz you could write that yourself, right. If you hover over it, you can see it's got a very simple implementation.

You could take a look, you could figure it out, but it is there as a utility method for you. And I like the help, I'm here for it. Cool, so as we saw props with children, and we're gonna use this a little bit later. There is component props and component parts without ref and with ref.

The ref is in React 18, I think, we had forwarded refs possibly a little earlier than that. And so whether or not you wanna actually define that, I tend to use without ref until I know I need to pass a ref through, cuz I just want the simplest possible solution.

But this will actually be all of the props from just a regular HTML button in this case, so you can pass it the name of any HTML string, which includes children in this case, too. And the cool part is you can pass them all through. Previously, you could actually in React 17, you could say like, hey, if this is a React.component or functional component, and children was implicitly included in there, that was removed.

There is a very long article for the proposal and the change, explaining all the reasons why, that I am not going to, somewhat academic. It's there linked for your own interest on the rationale. But it kind of gets into some of the nuances of how the amount of TypeScript that we definitely need to build our apps is different from the amount that you need to build the entire type system for React or style components or something along those lines.

But there is a lot written out there. If, at the end of our time together, you're like, yes, I would like to dive deeper, I've included some links towards the end, awesome.
>> Excuse me.
>> Yep.
>> Quick question. There you hard coded the button as a type and the generic, where without the ref thing, I was curious if there's a better way cuz technically that's still, we're trying to be super type safe.

The button is a string, we might make a typo. Is there button prompts or something?
>> So this button under the hood, let's see, let's pull one out and take a look. Let's learn it, let's follow my own advice, right? So let's actually grab this real quick cuz we don't even need to use it.

So it looks like it's just a string, but one of things we're actually gonna see in a little bit is, and I think you pointed this out earlier, with types I can have unions between them. So under the hood, for instance, if I do make a typo, I get yelled at, right.

And we'll actually see a little of how this works when we make a reducer actions in a little bit. But if I look under the hood, we can see that component props without ref, that generic extends element type, keep going, right. Element type tries to figure out whether it's an actual another React component or if it's one of the ones that's just an intrinsic element HTML element and JSX, keep going.

And you can see that it's actually using the key of just every valid HTML element, so it's gotta be one of these keys. So even though it looks like a string, it is a limited set of strings so you can pass it.

Learn Straight from the Experts Who Shape the Modern Web

  • In-depth Courses
  • Industry Leading Experts
  • Learning Paths
  • Live Interactive Workshops
Get Unlimited Access Now