DEV Community

Nhan Nguyen
Nhan Nguyen

Posted on

Zod - TypeScript-first schema declaration and validation library #8

Image description

Be Specific with Allowed Types

We will validate forms again in this example.

const Form = z.object({
  repoName: z.string(),
  privacyLevel: z.string(),
})

export const validateFormInput = (values: unknown) => {
  const parsedData = Form.parse(values);

  return parsedData;
}
Enter fullscreen mode Exit fullscreen mode

This time Form has a privacyLevel that can be two types: either private or public:

const Form = z.object({
  repoName: z.string(),
  privacyLevel: z.string(),
});
Enter fullscreen mode Exit fullscreen mode

If we were going to represent this in TypeScript, we would write:

type PrivacyLevel = 'private' | 'public'
Enter fullscreen mode Exit fullscreen mode

Of course, we could use a boolean here, but we may need to add more privacy levels in the future. It is often safer to use a union type or an enum here as well.

We will find an API in Zod that allows you to be more specific with the types of strings that can be passed into the validator function.

There are two possible solutions to this example:

One Solution: Use Unions & Literals

In the first solution, we will use Zod's union method and pass in an array of literals for "private" and "public":

const Form = z.object({
  repoName: z.string(),
  privacyLevel: z.union([z.literal("private"), z.literal("public")]),
});
Enter fullscreen mode Exit fullscreen mode

Literals can be used to represent numbers, strings, or booleans. They cannot represent objects.

We can use z.infer to check our Form type:

type FormType = z.infer<typeof Form>
Enter fullscreen mode Exit fullscreen mode

An Arguably Cleaner Solution: Enum

Using Zod enums with z.enum does exactly the same thing under the hood:

const Form = z.object({
  repoName: z.string(),
  privacyLevel: z.enum(["private", "public"]),
});
Enter fullscreen mode Exit fullscreen mode

We can use sugar syntax to parse literal values instead of using z.literal.


I hope you found it useful. Thanks for reading. 🙏
Let's get connected! You can find me on:

Top comments (0)