Intermediate React, v2 Typing a Class Component
This course has been updated! We now recommend you take the Intermediate React, v5 course.
Transcript from the "Typing a Class Component" Lesson
>> Brian: So let's go fix another one, let's go fix details,js here. So I'm gonna go to details.js, we wanna say rename, and we want to rename this .tsx and obviously it's gonna be upset about a great many things.
>> Brian: So first of all, it's gonna be upset by carousel and error boundary because those aren't typed yet.
[00:00:20] And we have it in strict mode, which basically means we don't accept any ANYs, right? And ANY is like, it doesn't know what carousel is. So it's just like, I don't know what this is, and I'm upset about it, right? So it's gonna be underlying this in red, this is going to be an error until you go type this one as well.
[00:00:41] So probably correct order of things is we probably could've gone and done carousel and error boundary first, but we'll get to it. So for now let's just deal with these kinds of errors.
>> Brian: So the first thing to know is that, React, you have to tell it what kind of props it's gonna get, for classes that is.
[00:01:01] So we're gonna give it a type parameter here, and we're gonna say that this is a RouteComponentProps. And you can see there that it's like, I think I know what that is, right? So if I click that it's gonna grab that from reach router.
>> Brian: And then this in of itself, these RouteComponentProps also takes another parameter.
[00:01:24] So it's like a function call within a function call and we have to tell it what kind of things you can expect to get. So we're gonna tell that, hey, we're expecting to get an id, and that's gonna be a string.
>> Brian: Okay, so now it knows that this.props.id is either gonna be a string or undefined, right?
[00:01:48] Because what happens if they get to the details route without getting an id, right? So we have to provide for that. So what happens when we get to componentDidMount and there's no string? Well, you're in a world of hurt. You need an id or you should not be on the details page.
[00:02:05] We tell that RouteComponents, right, that's going to get a parameter of id:string. Now, it's basically gonna say, I think you're gonna get an id, but it might not come right? So that's what the id? is, like, I don't know, it might come. So that means we have to provide for what happens if it's not there.
[00:02:25] So what happens if we get to the details page and there was no id provided? That's what you and I need to decide right now. Well, if you get to this page and there's no id, you can't stay on this page because I can't show you any pet if I don't have any id for the pet to show you.
[00:02:41] So we're just gonna say if there is no this.props.id, you're gonna say navigate to /, so go back to the homepage and then return. So that takes care of part of this. So now we know by the time we get down here, this is definitely here, it's definitely gonna be there.
[00:03:05] But the problem is pet.animal expects what? It expects that to be a number, right? So let's just do a little of magic here and say well now you're a number [LAUGH] right? So if I put that unary plus there it's gonna coerce that from a string into a number.
[00:03:25] Okay and then now it says okay, I know what an animal is and an animal has a name. And that's a string, and it has a type. And that's a string, and it has an address. And that's an object that's an address type. And if I click on that, I can go, okay, well, address here.
[00:03:42] And then it has an address here, right? Now I'm just looking at the type definition. So I can see what does an organization look like? It always has a name, but it has an email or it doesn't, right? So this is pretty good documentation that I can look at.
[00:03:58] It's fantastic because I wrote it. Just kidding, well I mean I did write it but it's not fantastic. And I just set up by doing Cmd + click on something here. Like I can just Cmd + click on contact, and it can take me into the type definition to see what that looks like.
[00:04:13] Or you can just hover on it, and if I had written JS docs, you would've seen those here as well, right? Whereas if I look at React.Component here, that one doesn't have it either. Some of these will have bits of documentation with it as well. Like if you do documents.querySelector, something like that, right, these ones are super well documented.
[00:04:40] It will tell you, returns the first element that is a descendant of the node that matches the selectors, right? So it actually has inline documentation. But that requires that the person is not a lazy teacher, and previously did that which I did not.
>> Brian: Okay, so that takes care of this.
[00:05:03] One of the things that any modes going to really, really encourage us to do we don't have to, you can see that these are warnings, not errors. Is that it wants to know is, is this public or is this private? Well, everything in react component is being called by react.
[00:05:17] So it's technically gonna be public, right? So I'm just gonna say this is a public state and this is a public component. ComponentDidMount that is, right, cuz react is calling into these things. But if I said like,
>> Brian: private thing = blah. So now this is private, TypeScript will catch if anyone else is trying to call, it's like no, no, no, that's private, you don't get to touch that, right?
[00:05:46] Whereas if it's public then it's okay for other things to access it, but now TypeScript will be the enforcer to make sure these things are private. Which is pretty cool as well. We won't be using that today, but I just wanted to call that out as something that I liked.
>> Brian: Okay,
>> Brian: Everything else here, it's able to figure out pretty well. I mean, this, it doesn't really care for. If you want to, you can type this and say this is gonna be an error. And you'll have to put these in parentheses. But now it knows like okay, this is an error.
[00:06:24] So you can give little hints here and there. All of these, we're gonna say public.
>> Brian: this.state.url, it's like hey, I don't know what that is. So can you tell me what this.state.url is? And it's like, I don't know what these are either. So there's two ways we can handle this.state being unknown.
[00:06:46] One of them, we could go up here and we can give it a second parameter after the RouteComponents here. So the first one is props, the second one is state. Or in my opinion, better if we go set a default value for all of these, TypeScript will figure everything out just on its own, right?
[00:07:03] So if I say, I'm just gonna go get a default value for name, that's going to be "" animal, "", location, "", description, "", media. That's gonna be an array. url is "" and breed is "".
>> Brian: So now it knows okay, if I say this.state.animal, that's gonna be a string.
[00:07:40] You told me that.
>> Brian: This only works with public class properties. If you're doing this inside of a constructor, this doesn't work. You do have to actually use this other method of saying, okay, this is gonna be this and that and whatever, right? So the S part of this is the state that you're gonna give it.
>> Brian: But because we have public class properties, it knows how to understand this. So we have one more problem. So notice that all this stuff is fine now. We have one more problem, probably.
>> Brian: Notice that the type here on this media is a never. That's not a good thing, right?
[00:08:23] This basically means like, all right you told me this is an array, but you didn't tell me what kind of array it is, so I'll let you have an array, but never touch it, [LAUGH] right? That's kind of what it's telling you here. So we have to tell it what kind of stuff is gonna go into it.
[00:08:38] So I'll show you how to do that. You're gonna come up here to media and you're gonna say as Photo[ ]. And so Photo is going to come from frontendmasters/pet right here. So this is gonna be a Photo.
>> Brian: Now,
>> Brian: If I go down here and look at media, wherever that went, media.
>> Brian: It's gonna say okay, cool, you can use that now.
>> Speaker 2: Can you use multiple media types like video, for example?
>> Brian: You definitely could, and then you would have what's called a union type, right? So then you would have to show TypeScript if this is of type video, then it has these kind of things, right?
[00:09:29] And you have to do some what's called type refinement to figure out which kind your dealing with, but it can be mixed, right. I don't know if I'm gonna show you anything like that today, but just look up type refinement, and you'll see.
>> Brian: Cool, that was a good question.
>> Brian: Okay, down here, we're gonna say, it's not like I don't know what these props are and I'm uncomfortable about that. So the first thing we're gonna tell it here is,
>> Brian: These props are gonna be exactly the same as these ones up here. So you can actually just Copy+Paste these ones.
[00:10:13] The routeComponents with the string in there. And we're just going to pass that into that, like that.
>> Brian: And then everything is happy.
>> Brian: And I think the only thing that it's upset about right now is these two imports at the top, right? So you can see there I have red right there, and it's like, hey there's problems with this file, right?
[00:10:43] But for now I can't fix these until I go and fix these other files. But so if I turn strict mode off of here, then it would be fine.