Now let's go do useBreedList.tsx. Before that, add this to APIResponseTypes.ts
export interface BreedListAPIResponse {
animal: Animal;
breeds: string[];
}
Now onto useBreedList.tsx
// import at top
import { Animal, BreedListAPIResponse } from "./APIResponsesTypes";
const localCache: {
[index: string]: string[];
} = {};
type Status = "unloaded" | "loading" | "loaded";
// change function signature
export default function useBreedList(animal: Animal): [string[], Status] {
const [breedList, setBreedList] = useState([] as string[]);
const [status, setStatus] = useState("unloaded" as Status);
…
}
// TypeScript wants to explicitly say that you don't care about returned promises
void requestBreedList();
// cast API response
const json = (await res.json()) as BreedListAPIResponse;
- localCache can have anything as a key so we need to let TypeScript know that. We have a generic "index" key that could be anything, and we're letting TypeScript know that only string arrays can be set as values.
- Like Animal, we can only have one of three possible strings for our Status so we can make that explicit and TypeScript can keep track of that.
- Since
[]
and"unloaded"
aren't explcit enough for TypeScript know that those are astring[]
or aStatus
, we can cast them to TypeScript definitely knows what they are. - Our linting rules make us explicitly ignore promises returned if we're not going to use them, hence the
void
. - Again we have to cast our API response into the type we know it's going to be.