TypeScript will show us all the methods that we have available on our API along with our hooks we use to consume our API. In addition to this, we'll get situational typing that will tell us what data is available to us given a loading state. This will catch a lot of bugs in our code.
Instructor: [0:00] Now, let's convert this application to TypeScript to see how that would look like and what benefits we get from it. I'll rename our index.js file to index.tsx and we see a few errors popping up. To get rid of this error, let's just add a assertion and move on by typing our components. [0:19] At first, we have a PokemonList. It gets a prop of onPokemonSelected. Let's type this as a function returning void and taking an argument of string. Also, let's go down to the PokemonDetails component and also type this pokemonName here should be a string.
[0:50] Now that we have done this, we can go and type our endpoints.
[0:55] For that, I already prepared some interfaces we can use for the API responses, so let's just paste them here. Take this and now, we say that this PokemonList is a query that returns our PokemonList and takes no arguments.
[1:16] We do that by specifying void. Then we go into our PokemonDetail and also type this. The ResultType here is PokemonDetailData and as an argument type, we take a name of type string.
[1:39] This leaves us with two different error types here. For one, it says the PokemonDetails and PokemonList are not valid components and the other says that onPokemonSelected doesn't have the right signature. For onPokemonSelected, let's say this is a useState of string or undefined.
[2:00] That will make this error go away and let's take a look at the other thing. The other thing is that these components have a fourth state next to isLoading, isError, and isSuccess. If that fourth state would occur, we would return undefined and it would not be a valid component.
[2:21] This fourth state actually cannot really occur here since we would have to use the skip option for that, but it is here. TypeScript warns us about. Let's also take isUninitialized from here and just say if isLoading or Uninitialized.
[2:42] Then if we hover over isSuccess here, we will see that it's always 1.
[2:48] If these three cases are not the case, this will be always 1. We can just remove the check and we don't need isSuccess anymore. Then let's do the same down here in the other component. Instead of isSuccess, we check for isUninitialized and we can remove this check for isSuccess because data at this point will always be PokemonDetailData anyways.
[3:19] With that, we have converted it to TypeScript. What do we gain from TypeScript here? For one, our API is typed correctly now. We can inspect it and we get all these things here. We don't only have a usePokemonListQuery, we also have a useLazyPokemonListQuery and we also have some other properties here that we will explore another time.
[3:46] Apart from that, we can take a short look at the hooks. We've already seen this give us these loading states. There's a little more in here. We also have a refetch method. We get a status. We can get the error in error cases. We get a fulfilledTimeStamp, etc.
[4:04] If we look at data up here, it says it's either PokemonDetailData or undefined. If we would access it here in isLoading, it would say it's undefined. But if we access it down here, after we exclude it, isLoading, isUninitialized, and isError, it says the data will always be of type PokemonDetailData.
[4:30] This type of situational typing will prevent a lot of bugs.