Zod Tutorial (10 exercises)
Problem

Create an Array of Custom Types

In this example, we're still using the Star Wars API but this time we want all of the people it returns.

The starting point is similar to what we saw previously, where the StarWarsPeopleResults variable is set to z.unknown().

const StarWarsPeopleResults = z.unknown();

export const fetchStarWarsPeople = async () => {
  const data = await fetch("https://swapi.dev/api/people/").then((res) =>
    res.json(),
  );

  const parsedData = StarWarsPeopleResults.parse(data);

  return parsedData.results;
};

Similar to before, adding console.log(data) to the fetch function shows us a lot of data even though we are only interested in getting an array of names.

If this was a TypeScript interface, it might look like:

interface Results {
  results: {
    name: string;
  }[];
}

Challenge

Update StarWarsPeopleResults to use an object schema that represents an array of StarWarsPerson objects.

Reference the previous lesson and the Arrays section of the Zod docs for help.

Transcript

Matt Pocock: We've got a different problem this time. We're actually fetching from a different API endpoint on Swapi. We're not fetching all of the people. All of the people here, the way this looks is it's kind of like an interface. Let's say Results {. It's got results: . This is an array of objects. It's name: string; basically.

If we console.log this data that's coming back, you'll be able to see what's going on because, again, we've got some text down here to say expect StarWarsPeople to equal this. You can see there that inside the console.log here, there we go, there's an enormous amount of data in here, but it's inside a results object here.

There are some other keys, too, like the count, like the results here. We've got to find some way of representing an array inside Zod because we need to reuse this StarWarsPerson.

We've got our name. We can add eye color if we want to. This just isn't working at the moment because it's not parsing the data correctly and we're getting a type error here.