Skip to content

Support circular object validation #5346

@kettanaito

Description

@kettanaito

Hi!

I'm proposing Zod supported validating circular objects. Here's what I mean by a circular object:

const user = {
  id: 1,
  posts: [
    {
      get author() { return user }
    }
  ]
}

user.posts[n].author is a circular reference back to the root user.

Motivation

  1. Circular objects are valid objects in JavaScript. You can certainly create them and they come in handy in data modeling libraries, e.g. when resolving relations between objects.
  2. Zod supports declaring such objects through getters, but it fails to validate them. This makes me feel like this is a bug that has to be addressed. What happens is Zod crawls circular references infinitely since user.posts[n].author points back to the user, which has user.posts, etc.

Proposal

I'd love for this to be solved with the minimal involvement from Zod. Here's what I suggest:

function parse() {
  const visitedNodes = new Set()

  function zodCrawler(value) {
    if (isObject(value)) {
      if (visitedNodes.has(value)) {
        return
      }

      visitedNodes.add(value)

      // ...continue with the validation.
    }
  }
  
  // Once the validation is done.
  visitedNodes.clear()
}

Following this algorithm, the aforementioned user example would result in the following steps:

- user
  - id (validate z.number()),
  - posts (array, fall through recursively)
    - author (the same user ref, skipping)

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