If you want to validate an array of objects from this Schema

const fieldsOfEng = [
  {
    id: "ELECTRICAL",
    name: "Electrical",
    experience: 1,
  },
  {
    id: "MECHANICAL",
    name: "Mechanical",
    experience: undefined,
  },
];

I'd do it like this

const userInfoSchema = z.object({
  id: z.string(),
  name: z.string(),
  experience: z.number().optional()
})

// Now add this object into an array
const usersInfoSchema = z.array(userInfoSchema)
Answer from Ark on Stack Overflow
Top answer
1 of 3
43

If you want to validate an array of objects from this Schema

const fieldsOfEng = [
  {
    id: "ELECTRICAL",
    name: "Electrical",
    experience: 1,
  },
  {
    id: "MECHANICAL",
    name: "Mechanical",
    experience: undefined,
  },
];

I'd do it like this

const userInfoSchema = z.object({
  id: z.string(),
  name: z.string(),
  experience: z.number().optional()
})

// Now add this object into an array
const usersInfoSchema = z.array(userInfoSchema)
2 of 3
8

This answer is an update on my progress so far. I closer to getting my schema validation working correctly but for some reason it is not submitting. I could solve this faster if I could get react-hook form's errors to output correctly but since I'm using template literals when I'm registering the inputs, the error is just outputting nothing. I DO know there is an error though because my truthy error outputs the "professions:" string that I added in the p-tag.

Data for checkboxes in form (this is the data I'm validating via zod):

const fieldsOfEng = [
  {
    id: "ELECTRICAL",
    name: "Electrical",
    experience: undefined,
  },
  {
    id: "MECHANICAL",
    name: "Mechanical",
    experience: undefined,
  },

Schema for validation: I'm checking that the name they select is included in my fieldsOfEng array and making sure the experience is greater than 1.

const userInfoSchema = object({
professions: z
    .object({
      name: z
        .string()
        .refine((name) =>
          fieldsOfEng.map((field) => field.name).includes(name)
        ),
      experience: z.number().refine((experience) => experience > 1),
    })
    .array(),
});

React hook form:

type userInfoType = z.infer<typeof userInfoSchema>;

  const {
    register,
    watch,
    handleSubmit,
    formState: { errors, isSubmitting },
  } = useForm<userInfoType>({
    resolver: zodResolver(userInfoSchema),
  });

Form: Notice I am using template literals for registering each input. It took me forever to figure this out. So far this is the only way I've been able to get the data to output correctly (via react-hook-form's 'watch' method).

<fieldset>
      <legend>Practicing fields of engineering</legend>
      {fieldsOfEng.map((field, i) => {
        return (
          <div key={field.id}>
            <div>
              <input
                {...register(`professions.${i}.name`)}     <--REGISTERED HERE
                value={field.name}
                type="checkbox"
              />
              <div>
                <input
                  {...register(`professions.${i}.experience`)}    <--REGISTERED HERE
                  type="number"
                  value={field.experience}
                  placeholder="Yrs Experience"
                />
              </div>
            </div>

            <div>
              {errors.professions && (
                <p>
                  professions:
                  {errors.professions.message}
                </p>
              )}
            </div>
          </div>
        );
      })}
    </fieldset>
🌐
Zod
zod.dev
Intro | Zod
import * as z from "zod"; const User = z.object({ name: z.string(), }); // some untrusted data... const input = { /* stuff */ }; // the parsed result is validated and type safe!
Discussions

Validate items uniqueness in z.array
I believe a lot of people could use this. i tried searching for opened issues regarding this but couldn't find anything other then this ongoing discussion. if this is already worked on i would ... More on github.com
🌐 github.com
3
September 21, 2025
Allow array to return only valid items and not fail whole array
I tried using refine on the array, but it seems to only be called when the array validates correctly. Is there a way to do this, or is this something you'd be willing to support? Beta Was this translation helpful? Give feedback. ... I don't know if Zod maintainers will support this specific ... More on github.com
🌐 github.com
6
2
PSA: You can have arrays with a minimum length.
This is really cool. Does someone have a use case where it is useful? When I'm working with arrays, being empty is pretty much always a valid use case. Datasets returned by the API, user selected options, etc. More on reddit.com
🌐 r/typescript
69
80
December 20, 2024
A tool to visualise Zod validation errors
Hi there, author here. I work on code generator that creates TypeScript SDKs from OpenAPI specs and Zod is a critical building block that I chose to power runtime validation in those SDKs. Depending on the complexity of a Zod schema, the resulting validation error message can contain a wall of JSON text - the serialised issues that were recorded during validation. I wanted to try and create a small tool to help me better visualise and parse these errors. In code and the command line, we do also have the ability to pretty-print the errors but I still wanted a web UI which can let me share URLs for visualised errors. I'm still iterating on it but would love any feedback if you do get to try it out. More on reddit.com
🌐 r/typescript
6
57
October 1, 2024
🌐
Telerik
telerik.com › blogs › zod-typescript-schema-validation-made-easy
Zod + TypeScript: Schema Validation Made Easy
November 3, 2025 - The PersonSchema contains the AddressSchema as a nested property, demonstrating how complex data structures can be validated recursively. Zod automatically handles array validation with z.array() and provides default values with .default().
🌐
Tecktol
tecktol.com › home › zod › zod arrays: from basics to array of objects validation
Zod Arrays: From Basics to Array of Objects Validation - Tecktol
March 30, 2026 - Each element in the array must be a number, and the entire array will fail validation if any item doesn’t meet that requirement. ... Handling errors in Zod arrays ensures that invalid or unexpected array data is caught and managed gracefully.
🌐
Zod
zod.dev › api
Defining schemas | Zod
Every Zod schema stores an array of refinements. Refinements are a way to perform custom validation that Zod doesn't provide a native API for.
🌐
Nicoespeon
nicoespeon.com › en › 2026 › 03 › decoding-arrays-with-zod
The Proper Way to Decode Arrays (with Zod) — @nicoespeon's blog
March 23, 2026 - z.array(SomeSchema) is the go-to way to validate arrays in Zod. But it has a catch: if any item fails parsing, the whole array is rejected.
🌐
Chrisgriffing
chrisgriffing.com › blog › custom-zod-oneof-validator
Custom Zod oneOf validator | Chris Griffing
June 28, 2024 - If you want to validate for a value being from an array you might use z.enum. However, if you read the docs for Zod enums you might notice that they require you to use z.enum directly or you can pass an array to z.enum as long as you define ...
Find elsewhere
🌐
Tighten
tighten.com › insights › form-validation-with-type-inference-made-easy-with-zod-the-best-sidekick-for-typescript
Form Validation with Type Inference Made Easy with Zod, the Best Sidekick for TypeScript | Tighten
March 28, 2024 - Represents an array of items being purchased. Each item includes an ISBN (must be a valid ISBN) and quantity (an integer between 1 and 5). ... Requires the customer's card number (must be a valid credit card number), expiration date (in the ...
🌐
Medium
rasitcolakel.medium.com › exploring-zod-a-comprehensive-guide-to-powerful-data-validation-in-javascript-typescript-2c4818b5646d
Exploring Zod: A Comprehensive Guide to Powerful Data Validation in JavaScript/TypeScript | by Raşit Çolakel | Medium
June 11, 2023 - Sometimes you need to preprocess data before validating it. For example, you might want to trim whitespace from a string before validating it. You can do this with zod.preprocess(). Or, you use zod the validate API request bodies, you can use it for boolean or number values.
🌐
GitHub
v3.zod.dev
TypeScript-first schema validation with static type inference
TypeScript-first schema validation with static type inference
🌐
GitHub
github.com › colinhacks › zod › discussions › 2316
Validate items uniqueness in `z.array` · colinhacks/zod · Discussion #2316
import z from 'zod'; function zUniqueArray< ArrSchema extends z.ZodArray<z.ZodTypeAny, 'many'>, UniqueVal >( uniqueBy: (item: z.infer<ArrSchema>[number]) => UniqueVal, schema: ArrSchema ) { return schema.superRefine((items, ctx) => { const seen = new Set<UniqueVal>(); for (const [i, item] of items.entries()) { const val = uniqueBy(item); if (seen.has(val)) { ctx.addIssue({ code: z.ZodIssueCode.custom, message: `Unique property validation failed`, path: [i], }); } else { seen.add(val); } } }); } const uniqueIdSchema = zUniqueArray( (obj) => obj.id, z.array(z.object({ id: z.number() })) ); // succeeds console.log(uniqueIdSchema.safeParse([{ id: 1 }, { id: 2 }])); // fails console.log(uniqueIdSchema.safeParse([{ id: 1 }, { id: 1 }]));
Author   colinhacks
🌐
P6p
zod.p6p.net › en › guide › arrays.html
Arrays | Zod
import { z } from "zod"; // Create array schemas const stringArray = z.array(z.string()); const numberArray = z.array(z.number()); // Alternative syntax const stringArray2 = z.string().array(); const numberArray2 = z.number().array(); // Validation stringArray.parse(["a", "b", "c"]); // passes stringArray.parse(["a", 123, "c"]); // fails
🌐
Turing
turing.com › blog › data-integrity-through-zod-validation
Schema Validation with Zod in 2025 | Turing
February 21, 2025 - The function first checks if the length of the array is greater than 3 and then adds an error message to be returned during validation along with a customized error code. The function also checks for duplicates and adds a second error message.
🌐
StudyRaid
app.studyraid.com › en › read › 11289 › 352183 › creating-array-schema-validations
Creating array schema validations - Zod
import { z } from 'zod'; // Define a basic array of numbers const numberArraySchema = z.array(z.number()); // Validate array of numbers const validArray = [1, 2, 3, 4, 5]; const result = numberArraySchema.parse(validArray);
🌐
DEV Community
dev.to › arafat4693 › learn-zod-in-5-minutes-17pn
Learn "Zod" In 5 Minutes - DEV Community
May 7, 2023 - All types in Zod have an optional options parameter you can pass as the last param which defines things like error messages. Also many types has validations you can chain onto the end of the type like optional
🌐
GitHub
github.com › colinhacks › zod › issues › 5267
Validate items uniqueness in z.array · Issue #5267 · colinhacks/zod
September 21, 2025 - the general idea is allowing to validate certain properties or the entire object as unique which will validate all properties in that array and will alert for duplicate values.
Author   colinhacks
🌐
GitHub
github.com › colinhacks › zod › discussions › 1824
Allow array to return only valid items and not fail whole array · colinhacks/zod · Discussion #1824
He can always throw provided error if result's data are insufficient. ... It should pass validation for all required (non-optional) fields and arrays with nonempty/min/max/length validator, otherwise returns { status: false, error }
Author   colinhacks
🌐
Tecktol
tecktol.com › home › zod › master zod validation: schema, typescript & documentation
Master Zod Validation: Schema, Typescript & Documentation - Tecktol
November 29, 2025 - When you combine Zod with React Hook Form, you get the perfect balance of type-safe validation and lightweight form handling. This integration makes it easy to validate fields like strings, numbers, arrays, enums, files, and even async checks — all while keeping forms fast and scalable.
🌐
Better Stack
betterstack.com › community › guides › scaling-nodejs › zod-explained
A Complete Guide to Zod | Better Stack Community
The output is a structured error object from Zod, where _errors at the root level is empty since there are no global errors. Each invalid field (name, age, email, password) has its own _errors array containing specific validation messages.