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

Mike demonstrates two different methods for adding types to React component props. The React.FC type is favored over using a custom interface because it would require less refactoring if any core React functionality changed in a future version.

Get Unlimited Access Now

Transcript from the "Typing React Props" Lesson

[00:00:01]
>> Yes, sir.
>> So in the past, for typing react components, I've just used an interface called props at the top of the component and not use the React.FC, is there an advantage to typing that? It's a functional component instead of just the props.
>> Can you talk me through what you do?

[00:00:18] I'm not sure I understand, like an interface called props?
>> Yep. And then-
>> Like that?
>> Whatever props I'm passing in, I would just type it in the parentheses of the function instead of the,
>> Over here.
>> Yep, so-
>> Is this with TypeScript or React props?

[00:00:40]
>> This is with TypeScript. So the Squiggly braces channel would equal props-
>> Llike this?
>> Yeah, colon props.
>> This will also work.
>> Just give it.
>> Yeah.
>> Can I show you where it won't work?
>> Yeah.
>> This works a fair bit of the time more than half, I would say.

[00:01:04] Let's look at loading. So we've got a message that's a string, and we don't have a good type here. Let's say message string, we can give it a nice type there. Format, please. Cool, let's add our props interface here and it's just this. Oops, sorry. So we can just delete this.

[00:01:46] Sorry, you wanted this here, props. We're already seeing a problem. The fact that we're using children means this approach won't work. Any time you're using children, you're gonna wanna use the built-in React types. Given, I wasn't doing React.props with children and wrapping it around the props interface before.

[00:02:11] But the approach of just inlining it, it works as long as you're only taking props in as arguments, not children but just props. And, you know, TypeScript's smart enough to know that you're returning a JSX fragment from loading, even without this type information here. There's your JSX element, so this matches like a childless React component.

[00:02:37] You can just infer your way to it, you know what's being returned, you know what you're taking it as an argument, it's perfectly fine. But as soon as children are involved you're gonna want to do it that way, so we'd say.
>> What I would do with the interface would just add children in the interface of props, and then you can put react node, and it will know that the children are they will know what he's talking about.

[00:03:04] So you can still use children with it?
>> You could.
>> Yeah.
>> Let's look at what react with child props.
>> You could also type the puram not as your props, props with children of props.
>> There you go.
>> So props as the generic argument there.

[00:03:20]
>> Yep, that's that's just what I was going towards because effectively props with children is doing what you're describing. So if we do it this way, just to finish the example. React props with children props, everything's happy, I don't see channel TSX lighting up here.
>> And if we look at this, here's your P, P is unknown, and look at that.

[00:03:54] You've been doing it the whole time. I mean, what you've been doing is correct.
>> Yeah.
>> This is just a name thing that also does the same thing.
>> Just more work for what I was doing.
>> More work? Yeah, this is a long thing to type out too, I just don't think either is incorrect.

[00:04:11] However, I do know that if React ever changes the way you describe children, in terms of the types, I'll get that benefit cuz I'm consuming it directly from React whereas, it's possible elsewhere. There have been times where React kind of changes things. There was a time I don't know if it was like 16 to 17 where you had to call super in like, pass an argument into super or something like that for class based components.

[00:04:37] Sometimes they change things up and if I grabbed their types and feed it right back to them, I think that maximizes the chance for compatibility. But nothing what you're describing, like nothing you're saying, seems harmful or short-sighted? It's literally the same thing, just expressed a different way.
>> One possibly minor advantage to long handing it the way that you have been is you can make children-

[00:05:02]
>> Defined.
>> Mandatory-
>> Yep.
>> If you need it for like a header, it doesn't make sense to have an empty header-
>> Like if-
>> Want children pass to you, so?
>> Yeah, it would give you at the call site, you know, some feedback that you can't use it as a self-closing component.

[00:05:24] Yeah, just different anyways, the skin and cat. I don't like naming my interfaces props, though, I will tell you that [LAUGH]
>> Why?
>> Because sometimes I want to grab this type and use it on the calling side, so I can create a variable that represents all of the props.

[00:05:41] I'm passing into a component, and I want to be able to do this. And now if I'm importing a bunch of different things called props I ended up having to do, I have to alias every single import. I would rather just prefix this with the component name or something like that.

[00:06:08] We'll leave this like this totally valid way to do okay, just making sure I'm staying on track here. We don't have to go like all the way through here, it's just more of the same where we would, here we could just say something like that, right? And as we're doing this, some things may flare up, and yeah, this is a much faster.

[00:06:37] But I don't think they will, Actually, I'm losing the thing that I was trying to do here, which was, Making sure I don't expose things to the wholesale representation of things, but I think you'll probably get this approach and how we continue to do this.