React and TypeScript, v2

React Component with TypeScript

Steve Kinney

Steve Kinney

React and TypeScript, v2

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

The "React Component with TypeScript" 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:

Steve begins refactoring a React component to use TypeScript. The file extension is renamed to use a .tsx extension. As types are added to the component, the editor will display errors where type conflicts occur. Errors can also be displayed in the terminal.


Transcript from the "React Component with TypeScript" Lesson

>> TypeScript component, all right? This is a TypeScript component, and my challenge for you is to try to delineate what uniquely makes it a TypeScript component. Yeah.
>> File extension is TSX?
>> Yeah, that's about it. If I change the file extension on this file, it would go from a TSX to a JSX and we go from TypeScript to JavaScript.

And this is, again, one of the main points that I wanna like double down on, which is, TypeScript tries its hardest to stay out of your way, right? It just tries to be helpful. If you find yourself out of the box, doing a ton of typing, that's probably an anti pattern, right?

Cuz TypeScript is gonna do everything in its power to figure stuff out. So even in this, if we hover over name badge, we can do that one, right? It knows that this is a function that takes no arguments and returns at JSX element, right? And so if I tried to use some other function in JSX, it wouldn't work, cuz it knows it's not returning a JSX element and it knows that this is a valid react component that's a function, right?

It just figure that all out on its own. Even if I hover over any of these elements, I kinda get the types and yeah, they look a bit much, but if you squint you can mostly figure out what's going on as I hover over that section, right? It's an HTML element, right?

Cool cool cool, of the section type, so on and so forth. Class names, you can see they can be a string or undefined. You can mostly try to use the inspiration of what the typing and react has already done for you, to kinda figure out what something should be.

Now, that said, this is no, not only is this both a TypeScript as well as a JavaScript component. I guess technically if it wasn't for class name, it was just classes would also be almost HTML, right? So to say they're almost the same, it's a little disingenuous because we haven't really done anything with this yet.

So there are usually some kind of react component either takes some kind of state or props, right, that's a thing, otherwise you would just handcraft HTML. And that is the case here as well, so for instance, we could throw in a prop,put a name for instance and you can see that TypeScript is starting to get angry with me, that's good.

I need it angry with me. So I have strict mode turned on for the entirety of this workshop. And if you're migrating a code base, you might still choose use strict mode. You might choose not to but for the purposes, especially if it's learning having all the rules in place, makes sense.

And so the first thing is, that name has implicitly an any type. It has an any type, any is like I don't know, YOLO, right? And what it's saying is, can you tell me what name is supposed to be so I make sure it has all the methods.

And if you look right now with name, if I put a dot after it, I get nothing. However, I can say, okay, here are the prop types. And a lot of times in regular JavaScript, you don't have to use that library called prop types, but you can to have react check to make sure, hey, you said name was supposed to be a string.

Is this a string? Because most of us have encountered what was previous and known as undefined as not a function or you call an array method on null or something along those lines. Most of the errors in our applications are type errors, right? And so having something to run in check, but TypeScript was able to figure out the return value of this but it doesn't know what is eventually gonna get passed in just by reading the code.

Now, that's something happens in practice. So whatever TypeScript can figure out for you, it does, you don't have to worry about it. However, anything that TypeScript can't figure out, you get gotta be a friend. You gotta help out, right? And so we can basically just say, all right, cool.

It's an object and name is a string. Now TypeScript is happy again, you can see the application TSX is immediately upset with me. All right, good, it ought to be upset with me I told it that the name badge takes name and I didn't give it a name in here.

So I can go. Cool, you save that, and I didn't even need to save for all those errors to happen as I typed all this checking was going on. I don't have to flip back to my browser see it crash go look at the console log get yelled at or sometimes in development mode react.

It'll show it to you, but I don't have to do that, I can instantly see tabs are changing colors. If I had the sidebar open, stuff would change colors there as well. It becomes really easy once you get used to just kind of following the flow, right? Especially if you're doing a refactor, which is sometimes perilous.

Especially if you don't have great unit tests, of course, you have great unit tests. Everyone has great unit tests, right? Having something immediately telling you the first time that you're using TypeScript. And you get all the red squigglies go away and then you flip over to your browser and you're like, big refactor just worked.

It all pays off. All right, so if this looks confusing to you at all, in TypeScript, a simpler version would be like. It's just the type of that argument, right? And so you can see this is takes a number, returns a number. I could specify that it returns a number as well.

I don't need to. I do this actually a lot though in a lot of my helper functions because sometimes I accidentally don't have a conditional or something along those lines. So sometimes it would be, don't ever return undefined or void in this case, make sure I get a number out of this.

I will sometimes type the return argument to keep myself honest, but if you don't, TypeScript will just look at the function and figure it out. So this kind of set of curly braces over here is the same as changing this just props Here as well, right? Everything is the same idea.

It's just regular TypeScript for function, and everything works as expected. The other cool part is now that knows it's a string. The only methods that show up here are string methods, right? So immediately, not only am I getting the safety and all the checking in my very complicated app as you can see.

But on top of that, my life is now more convenient cuz I've been doing this now for a really long time. There's a few methods that I will still never remember, like which one is which, right? Unshift verses push and shift and pop, pop and push I got, unshift and shift never, right?

And so remembering all of those and even some of the new ones that are all, which strings have includes the includes versus contains I'll never remember which one's on which. And the nice part is, because I'm using TypeScript, I don't ever have to learn, right? Cuz my editor and my compiler will just tell me.

I think this is what, when I started writing Ruby and JavaScript, and people who were coming from real programming languages, I would say like, strongly typed languages are better. I think I now know what I mean, like a decade later. So we have all this in place, everything kind of works and that's pretty great.

Now, be clear this works because this is a pretty standard function, right? If I did something, if you look at this function now, well, this could return a JSX element or no, right? And if that's what you want, that's great cuz now TypeScript will know that this function depending on how you call it can turn one or the other, right?

If however you are writing something the first time I will do this a lot. Which is, I will say no, make sure I return a JSX element, at which point it's hey, there is some condition here where you don't, right. And for me, this saves how many unit tests have you ever written, which this function is supposed to take a string, but what happens if I pass an undefined?

What happens if a number comes in? There's so many unit tests that we write and so one of the many other things I'm gonna try to pitch to you over our time together is, sometimes, yes, this is a little more work than just playing fast and loose with JavaScript.

Often times the number of unit tests that you save yourself, that you totally were gonna write. All bugs in production really? Will are cut down drastically, right? And if you're like I do these things all the time, just think of your least favorite teammate. Cool. So we have that all in place.

So what we can do now is figure out what does it mean to navigate from these props and stuff along those lines, there were other ways to do this, right? That's right there were prop types, if we look at over here at this control panel, which I'm not really using but it makes it this is a JavaScript file, JSX.

Two things to point out, I could import this file just fine. So if you're worried about migrating, react app from JavaScript to TypeScript, once you have the basic TypeScript set up, there's a property in the TS config called allow JS. Does anyone want to venture wild guess what that does?

Yeah, it allows us, right? That's right and so one of the things that we could do, one of things I'm gonna have you do, is kind of we're gonna try to transition this file from JavaScript to TypeScript. So,two major things,one, is that if you have prop types already kind of set up, it's fairly easy to do.

Two is that we know that JavaScript and TypeScript can live together pretty nicely. It's a little trickier when the TypeScript file is importing the JavaScript file to be totally honest cuz everything is in any type but it's kind of like you were just working with JavaScript, Beginnings are great nicely.

Then to converting is fairly easy. Mark.
>> I would see a couple of questions in chat around setup and configuration of TypeScript.
>> Yep, let's see.
>> Are we using create react app?
>> I am using create react app because I feel like it's a common standard denominator.

>> And are there any configuration, things you tend to use in TypeScript?
>> Yeah, I will show you just kind of the basic one that I use. Okay, so this is, I can't remember if this is the one that comes with create react app or doesn't want to paste it from another project.

I actually just made my own templates I do enough of these. This one I don't normally keep on if I'm starting a new project, which is allowed JS because I'm starting fresh. I don't need to create a future migration problem for myself, but this is, you know most of these are kind of standard, right?

As soon as you might want to target a later version of JavaScript ES5 is pretty safe. Yeah, obviously we're using JSX. I would see what else is kind of unique and important because mostly standard I almost always keep strict mode on Because when I don't and then I decided to turn it on later.

I then have to make things in strict mode. So some of these, I think these are very safe defaults. This one up here lets you just import react instead of like star from react, which you might seen in some TypeScript blog posts. So instant yeah, if it doesn't have a default export, you can just, it figures that out for you.

These are kind of, most of the cases, this is nice too, which is like if you have a case statement and you exhaust all the different options, right? You don't have to do the default thing. It'll like figure all that out for you. Again, stuff like strict mode, I might turn off if I'm migrating an app, right?

Allow JS, I might turn on if I'm migrating app, but generally speaking, this is a setup, please.
>> Yeah, there was another question around being able to run from the command line and see all the TypeScript errors throughout your project.
>> Yeah. Depending on your setup, so if you're using hvidt, or a modern version of Webpack, and you have the server running, you will see them, right?

I just couldn't see them in the editor, so I didn't but for instance, let's take this out and now the editor knows immediately that I have a problem. We got to change over. We gotta save that file. So, you'll notice that like I didn't see the error immediately in my web server because I didn't save all those files.

So the web server knows when you save the file, your editor knows immediately, which is also kinda nice during a refractor, right? Now that it will still be up and running and I can solve all the red squigglies and then go take a look, but you will see it in your terminal as well across your entire app, not just the file that you're looking at.

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