Intermediate React, v3 Typing The API Response
This course has been updated! We now recommend you take the Intermediate React, v5 course.
Transcript from the "Typing The API Response" Lesson
>> Let's go do Details next. So we're going to rename this Details.tsx. So before that, we have this thing here called, well, we have these animals that we use. Let's go and make a new file called API response type. So we're gonna actually make a file just of types.
[00:00:31] So we're gonna make a new file here, and we're gonna call it, inside of Source, and call it APIResponseTypes.ts. We're not gonna have any React in it so you could call it ts or tsx. I went with ts. There's not really good rhyme or reason, you can call it always tsx.
[00:00:52] You can call it always ts if there's no React in it. That's kind of up to you. Export type Animal. So we're gonna get into what is a type and what is an interface which is always a fun discussion to have. But let's just go ahead and do this one.
[00:01:10] Something that is of type animal is either gonna be a dog or a cat, Or a bird, Or a reptile or a rabbit. Now why did we do this? Because now we can say anywhere is like hey, we have this const friend and they're of type animal, and I wanna say it's a peacock, right?
[00:01:46] It's gonna say, hey, you can't actually do that, that's not assignable. So it's actually going to literally check is this a dog, cat, bird, reptile or rabbit. So it's literally checking like, I've been told that these are the only types of animals that I can handle. It will prevent you from doing it any other way.
[00:02:03] Okay, and we're exporting this because now we can import this and other files and say, hey, this thing's an animal, make sure it's always one of these types. So this is even more specific than a string type. I could have just said animals are always strings, but we know it's actually more specific than that.
[00:02:22] Okay, now we're gonna export an interface. And this is always the most confusing part for people. When do I use type? When do I use interface? And what's the difference? I'll be honest, it's confused me for a long time and I still sometimes have to look it up.
[00:02:37] So, I'm just gonna give you the just huge rule of thumb. When you can use an interface, use an interface. If it's possible to use an interface, always use interface because it's more flexible, it's easier to deal with. This is a time when we have to actually use a type.
[00:02:53] Now, it says type here, but really what it is is a type alias. So that alias term is actually a little bit important here. Because really what animal is, is we're just kind of restricting down a string. And that's really what this type animal is, that's why it makes kind of a type alias here.
[00:03:13] Whereas pet this is gonna be like an interface that other things can implement. But suffice to say it's just an object shape. And you can use types, aliases this way as well. So they have some overlap of when you can use each. And that's why I'm telling you the advice that I get from the TypeScript team is whenever you can use interface use interface.
[00:03:31] If you have some specific use case like this one here, we can only use a type alias, then do that. All right, so a pet that comes back from our API has an id which is a number. It has a name, which is a string. It has an animal which is a what, it's an animal.
[00:03:54] It has a description, which is a string. We have a breed, which is a string. We have an images, which is a string array. We have a city which is a string, and we have a state which is a string. And now we have a fully typed pet so that we can say, okay, this object here, it's a pet.
[00:04:23] This is what it has, this is what it doesn't have, so on and so forth. And then we can have a pet respond like a pet API response. Anytime that we can do a fetch from that API response, we're gonna have to cast it as a pet API response.
[00:04:39] So export interface, PetAPIResponse and it's gonna have a number of results, which is a number. It has a start index, which is a number, it has an end index which is another number. It has a hasNext which is a Boolean. And it has a pets array, which is what?
[00:05:10] It's an array of pet objects. And now we have some very useful flexible things cuz we have these pet responses in multiple parts of our apps. And now we just import these types that we can use other parts of our application. All right, so in the details, let's rename it details.tsx.
[00:05:31] We did that. From react-router-dom, we're gonna grab the RouteComponentProps. And then down here at the bottom, we're gonna import PetAPIResponse and Animal from ./APIResponseTypes, okay? So now we've imported these types, we can use them here. First thing we have class Details extends Component. And now we're gonna tell it what the shape of this component is.
[00:06:10] So the first thing is it's a RouteComponent. So we can say this is a RouteComponentProps. That's the kind of props it's gonna expect. And of those, so we're gonna kinda do two layers of generics here, it's going to expect an id string. So what is this saying? This is a RouteComponent that we got from react-router-dom.
[00:06:35] And that in and of itself can accept those Id like here, an app. This here, we have to identify to TypeScript. This is what it is expecting, from react-router-dom to be passed in as a parameter from that URL. Okay, so going back to details. That's how we get that.
[00:07:07] Now something we have to do here that we were being kinda lazy about here is we were just loading json pets in here, but it's gonna say, hey, I don't really know, or this is not gonna work for your state. So we kinda have to be more explicit and give it more defaults of what goes into state here.
[00:07:27] So we have to go identify, here's everything that's gonna come back from the PetAPI. So we have to say animal is gonna be empty string. But it's not just an empty string, it's what? It's an animal. So we have to say, actually, this is really an animal, it's not just a string, okay?
[00:07:49] Breed is gonna be an empty string. City is gonna to be an empty string. State is gonna be an empty string. Description, Is gonna be an empty string. Name is gonna be an empty string. And then images is gonna be an array, right? But we have to tell it what kind of array is it gonna be.
[00:08:16] Well, that's easy to do, you just say it's gonna be an array of strings. Okay, so we have to be a bit more explicit about what the state shape is gonna be, Okay? Is this upset about async? No, it's fine. So we have to say, what is coming back from this API, it doesn't really know.
[00:08:48] So what we're gonna do this, json is going to tell it. This, you can expect as a PetAPIResponse. So now this json is gonna know like this is called casting, right? And it doesn't know what API you're calling when, it's not that intelligent to really figure out, well, it's calling this and this has this shape, right?
[00:09:10] You have to tell it. This is gonna come back as that. And now it knows that this json is a PetAPIResponse. There's probably other ways to cleverly type this. And some people don't like using this as this casting of types but I find it's just really simple because now I know this json for sure is definitely gonna be a PetAPIResponse.
[00:09:40] Okay, this is upset that it's a, Location is actually a location type and we're kind of hacking around the browser API's here. The correct way of doing this is actually putting href here. And that's actually the technically spect way that's correct to do it. There's just like a browser.
[00:10:03] All browsers kind of implement the unspect behavior that if you reassign location, it respects that as well. This is gonna make you learn to spect a lot better, for good or for worse. Okay, so that's all good. Everything's happy here. Everything's happy down here. Most of the stuff that can pick up pretty easily with type inference but there's some places you just kind of just have to massage and help it out a little bit.
[00:10:29] Okay, ErrorBoundary here. This you have to tell that Detail. Let's actually make this a little bit easier. We're just gonna break this into another component and say const DetailsErrorBoundary is a function component. So I don't think I imported the top, but I'm just gonna have VS code auto import it for me and then I'll show you how to do that.
[00:10:58] So this is a function component, and it's equal to a function called details error boundary. You put the name there twice just so it's easier to debug. Cuz that'll show up in your stack traces. And then we'll just move this in here. And then export default DetailsErrorBoundary like that, Okay.
[00:11:28] Now I just kind of as a lazy rule, I'll pass down the props from just like this, but now what TypeScript is gonna demand to know is, hey, I don't know what those props are and I'm kind of uncomfortable with it. So for me, it's just easier just delete the props.
[00:11:48] Cuz right now we're not expecting any props, there's no reason that we have to have that. That's just something that I do. Now details should be nice and happy with everything in it. Okay, we've now gone through TypeScript2, that's the next checkpoint that we have there in our repo and we're gonna go do ErrorBoundary next.