✨ 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;
}
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(),
});
If we were going to represent this in TypeScript, we would write:
type PrivacyLevel = 'private' | 'public'
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")]),
});
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>
⭐ 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"]),
});
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:
Hashnode: https://nhannguyen.hashnode.dev/
X (formerly Twitter): https://twitter.com/nhannguyendevjs/