Zod Tutorial (10 exercises)
Problem

Reduce Duplicated Code by Composing Schemas

And now for something completely different.

In this exercise, we'll be looking at techniques how to refactor working code to remove duplication.

Here we have schemas for User, Post, and Comment:

const User = z.object({
  id: z.string().uuid(),
  name: z.string(),
});

const Post = z.object({
  id: z.string().uuid(),
  title: z.string(),
  body: z.string(),
});

const Comment = z.object({
  id: z.string().uuid(),
  text: z.string(),
});

Notice that id is present in each.

Zod provides us with various ways of composing objects together into different types, allowing us to DRY out our code.

Challenge

Your challenge is to use Zod to refactor the above code to remove the id duplication while still having the tests pass.

About the Test Case Syntax

You don't have to worry about the TypeScript syntax in the test cases for this exercise, but here's a quick explanation of what's going on:

Expect<
  Equal<z.infer<typeof Comment>, { id: string; text: string }>
>

In the above line, Equal is ensuring that zinfer<typeof Comment> and {id: string; text: string} are of the same type.

If you remove the id from the Comment schema, VS Code will draw a red squiggle below the Expect line because type false does not satisfy the constraint true.

Transcript

This exercise is a little bit different from the others because it's a refactor exercise. We've got some user and post and comment thing down here. What this is doing is there's a lot of duplicated code here. This ID is duplicated a bunch of times. There are various things in Zod that help you compose objects together into different types.

I've got some cases down here. Don't worry about the complicated TypeScript syntax here. What it's basically doing is we've got z.infer here inside this equal. If I just break this out a little bit, what equal is doing is it's making sure that this and this are of the same type.

If I say, "Comment," if I just remove the ID there...Sorry. That was in user there. User, it's not equal, these two things. Type false does not satisfy the constraint true because it doesn't have the ID property anymore.

Consider these three things of comment, post, and user. These are like your guides to make sure that the objects still represent what I want them to represent. Of course, if you run the exercise, then it's going to run the type check. If they're not passing, then it's going to tell you. Your challenge is to try to use some Zod APIs to make these objects a bit cleaner and a bit more dry.