Zod Conditional Requirements Based on Values in Array Field

Zod Conditional Requirements Based on Values in Array Field

When working with TypeScript, you may come across a situation where you need to enforce conditional requirements based on the values in an array field. This can be particularly useful when you want to validate certain fields based on the presence or absence of specific values in the array.

In this blog post, we will explore two solutions to this problem using the Zod library, which is a powerful TypeScript schema validation library.

Solution 1: Using Zod’s `refine` Method

The first solution involves using Zod’s refine method to define custom validation logic based on the values in the array field. Here’s an example:


import { z } from "zod";

const schema = z.object({
  arrayField: z.array(z.string()),
  conditionalField: z.string().refine((value, context) => {
    const { arrayField } = context.parent;
    return arrayField.includes("requiredValue") ? value !== "" : true;
  }, {
    message: "Conditional field is required when 'requiredValue' is present in the array field.",
    path: ["conditionalField"],
  }),
});

const data = {
  arrayField: ["requiredValue"],
  conditionalField: "",
};

const result = schema.safeParse(data);

console.log(result);

In this example, we define a schema using Zod’s object method. The arrayField is defined as an array of strings, and the conditionalField is defined as a string. We then use the refine method to add custom validation logic to the conditionalField based on the values in the arrayField. If the arrayField includes the value “requiredValue”, the conditionalField should not be an empty string.

The refine method takes a validation function as its first argument, which receives the value being validated and a context object containing the parent values. The function should return true if the validation passes and false otherwise. We can use the includes method of the array to check if the required value is present.

If the validation fails, an error message will be included in the result object returned by the safeParse method.

Solution 2: Using Zod’s `array` Method with `z.lazy`

The second solution involves using Zod’s array method in combination with z.lazy to define conditional requirements based on the values in the array field. Here’s an example:


import { z } from "zod";

const schema = z.object({
  arrayField: z.array(z.string()),
  conditionalField: z.lazy((value, context) => {
    const { arrayField } = context.parent;
    return arrayField.includes("requiredValue") ? z.string().nonempty() : z.string();
  }),
});

const data = {
  arrayField: ["requiredValue"],
  conditionalField: "",
};

const result = schema.safeParse(data);

console.log(result);

In this example, we define a schema using Zod’s object method. The arrayField is defined as an array of strings. The conditionalField is defined as a lazy schema, which means its definition can depend on the values in the arrayField.

We use the lazy method to define a function that returns a different schema based on the values in the arrayField. If the arrayField includes the value “requiredValue”, the conditionalField should be a non-empty string. Otherwise, it can be any string.

The lazy method takes a function as its argument, which receives the value being validated and a context object containing the parent values. The function should return a schema based on the condition.

Again, if the validation fails, an error message will be included in the result object returned by the safeParse method.

Conclusion

In this blog post, we explored two solutions to enforce conditional requirements based on the values in an array field using the Zod library. Whether you choose to use Zod’s refine method or the combination of array and lazy, you can easily define complex validation logic in your TypeScript projects.

Remember to install the Zod library using npm or yarn before using it in your projects. Happy coding!


Posted

in

by

Tags:

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *