Skip to content

ability to define inline non-empty array which is expressed in its inferred type (in v4) #6075

@tbknl

Description

@tbknl

Feature request

The change in z.array()'s .nonempty() between zod v3 and v4 (see migration guide) causes the inferred type to no longer express that the array contains at least one element T[] vs. [T, ...T[]].

The proposed solution in the migration guide is to use z.tuple([elementSchema], elementSchema). Please note that this requires to repeat the element schema. In case it's a non-trivial element schema, it's hard to read and maintain in case it is defined inline. Essentially, this forces the element schema to be stored non-inline, in a variable, which also impacts readability.

I'd like to request the feature to be able to define a schema for a non-empty array inline, without repeating the element schema.

Related tickets

There are already 2 issues about this change in inferred type:

Please note that the feature request in my issue is not necessarily about the change in inferred type, but about the ability to define an (inline) schema for non-empty arrays without repeating the element's sub-schema.

Proposed solution options

  • Change the inferred type of z.array()'s .nonempty() from T[] to T[] & [T, ...T[]].
  • Add a new function to z.array(), e.g. .withAtLeastOneElement() which behaves like .nonempty(), but having inferred type T[] & [T, ...T[]].
  • Introduce a helper, e.g. z.nonEmptyArray(elementSchema), which will behave the same as
    • either: z.array(elementSchema).nonempty(), but then with the inferred type of T[] & [T, ...T[]] or just [T, ...T[]]
    • or: z.tuple([elementSchema], elementSchema)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions