Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Recursive type: Type instantiation is excessively deep and possibly infinite. #577

Closed
JorikSchellekens opened this issue Aug 8, 2021 · 9 comments
Labels
wontfix This will not be worked on

Comments

@JorikSchellekens
Copy link

I'm running into a problem creating a parser for a fairly simple recursive type. The following errors with Type instantiation is excessively deep and possibly infinite. TS2589:

type V = [V] | "Null"

const V : z.ZodSchema<V> = z.lazy(() =>
  z.union([
    z.tuple([V]),
    z.literal("Null")
]))

However a loosely similar type works fine:

interface V {
  a: [V]
}

const V : z.ZodSchema<V> = z.lazy(() => 
  z.object({
    a: z.tuple([V])
  })
)

The use of the Tuple is significant, using an array works fine for both.

I'd be willing to work on a pr but I had a poke around and didn't get far in finding out what causes this, if you have any tips on what might be causing it I can take another look.

@colinhacks
Copy link
Owner

colinhacks commented Aug 13, 2021

This works if you do this:

const V: z.ZodSchema<V, z.ZodTypeDef, any> = z.lazy(() =>
  z.union([z.tuple([V]), z.literal("Null")])
);

The third generic parameter to z.ZodSchema is inferred from the first, and apparently passing a self-referential type in that case causes TypeScript to panic. 🤷‍♂️

@JorikSchellekens
Copy link
Author

JorikSchellekens commented Aug 15, 2021

An equivalence check gone wild? Thanks for the easy workaround!

@takahash
Copy link

takahash commented Aug 25, 2021

A similar error occurs when TypeScript version is 4.3 or higher.

const C = z.object({
  foo: z.string(),
  bar: z.number().optional(),
})
utils/validations/schema.ts:4:11 - error TS2589: Type instantiation is excessively deep and possibly infinite.
4 const C = z.object({
            ~~~~~~~~~~
5   foo: z.string(),
  ~~~~~~~~~~~~~~~~~~
6   bar: z.number(),
  ~~~~~~~~~~~~~~~~~~
7 })
  ~~

I'm using TypeScrip version 4.1.5 now because I don't get this error with the version.
Next.js recommends TypeScript version 4.3.2 or higher, so if anyone knows how to avoid this error, please let me know.

@colinhacks
Copy link
Owner

@takahash do you have a reproduction repo?

@nikhilag
Copy link

@takahash What version of Zod were you using with Typescript 4.3.2? In my case I experienced the same issue with tsdx because internally they were using a very old version of typescript. I haven't tried with NextJS yet.

@takahash
Copy link

@colinhacks @nikhilag

I'm sorry, when I tried a little more, it seemed that the cause was that the zod was read in different files.

schema.ts

import { z } from 'zod'

export const C = z.object({
 foo: z.string(),
 bar: z.number().optional(),
})

validate.ts

import { z } from 'zod'

type Value = { _errors: string[] }

export const handleValidate =
 (schema: z.ZodObject<any>) => (values: unknown) => {
   let formattedErrors: Record<string, string> = {}
   try {
     schema.parse(values)
   } catch (error) {
     if (error instanceof z.ZodError) {
       const errors = error.format()
       Object.entries(errors).forEach(([key, value]: [string, Value]) => {
         if (value._errors && value._errors.length) {
           formattedErrors[key] = value._errors[0]
         }
       })
       return formattedErrors
     }
   }
 }

When I put the above two files together, the error disappeared even if the TypeScript version is 4.3.2 or higher.
I don't understand the detailed cause of why separating files causes an error.

@scotttrinh
Copy link
Collaborator

@takahash

This sounds similar to an issue where you might have two different versions of zod installed? Are you exporting C into a different project that might have a different version of zod also declared?

@kotx
Copy link

kotx commented Oct 16, 2021

I saw this in my vscode hints but nowhere in my actual builds. Turns out I had to uninstall the ts-next (Microsoft TypeScript Nightly) extension from vsc.

@stale
Copy link

stale bot commented Mar 2, 2022

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
wontfix This will not be worked on
Projects
None yet
Development

No branches or pull requests

6 participants