Generating type definitions for a library with zod and i get an error
isaacfink opened this issue · 7 comments
I am getting this error when running build command
[vite:dts] Start generate declaration files...
src/cards.ts:3:27 - error TS2589: Type instantiation is excessively deep and possibly infinite.
3 const categoryValidator = z.object({
~~~~~~~~~~
4 label: z.string(),
~~~~~~~~~~~~~~~~~~~
...
6 group: z.string()
~~~~~~~~~~~~~~~~~~
7 });
~~
the categoryValidator
is only referenced once in the same file so I am sure it's not a circular dependency, what could be causing this? It's annoying to debug this because it takes vite over 30 minutes to give up which means I have to wait 30 minutes before I get the error
Edit: I removed this validator and added it inline but I was still getting the same error, I didn't get to see the error because as mentioned it takes forever but it was there
This is the entire index file in the package
import { z } from 'zod';
const categoryValidator = z.object({
label: z.string(),
value: z.string(),
group: z.string()
});
export const textBlockValidator = z.object({
text: z.string({ required_error: 'default text is required' }),
textLines: z.array(z.string({ invalid_type_error: 'text lines must be an array of strings' }), {
invalid_type_error: 'text lines must be an array of strings',
required_error: 'text lines is required'
}),
fontFamily: z
.string({ required_error: 'font family is required' })
.url({ message: 'font family must be a valid url' }),
fontSize: z
.number({
invalid_type_error: 'font size must be a number',
required_error: 'font size is required'
})
.finite({ message: 'font size must be finite' })
.positive({ message: 'font size must be positive' }),
fontWeight: z.enum(['bold', 'normal', 'lighter', 'bolder', 'light'], {
invalid_type_error: 'invalid font weight, must be one of: bold, normal, lighter, bolder, light'
}),
fontStyle: z.enum(['normal', 'italic', 'oblique'], {
invalid_type_error: 'invalid font style, must be one of: normal, italic, oblique'
}),
charSpacing: z.number(),
lineHeight: z.number(),
textAlign: z.enum(['left', 'center', 'right'], {
invalid_type_error: 'invalid text align, must be one of: left, center, right'
}),
fill: z.string(),
left: z.number({ required_error: 'left is required' }),
top: z.number({ required_error: 'top is required' }),
width: z
.number({ required_error: 'width is required' })
.finite({ message: 'width must be finite' })
.positive({ message: 'width must be positive' }),
height: z
.number({ required_error: 'height is required' })
.finite({ message: 'height must be finite' })
.positive({ message: 'height must be positive' }),
direction: z.enum(['ltr', 'rtl'], {
invalid_type_error: 'invalid direction, must be one of: ltr, rtl'
}),
opacity: z
.number()
.max(100, { message: 'opacity must be less than or equal to 100' })
.min(0, { message: 'opacity must be greater than or equal to 0' })
.optional(),
hiddenField: z.boolean(),
id: z.string(),
maxLines: z.number({
required_error: 'max lines is required',
invalid_type_error: 'max lines must be a number'
})
});
export const imageBlockValidator = z.object({
id: z.string(),
left: z.number({ required_error: 'left is required' }),
top: z.number({ required_error: 'top is required' }),
width: z
.number({ required_error: 'width is required' })
.finite({ message: 'width must be finite' })
.positive({ message: 'width must be positive' }),
height: z
.number({ required_error: 'height is required' })
.finite({ message: 'height must be finite' })
.positive({ message: 'height must be positive' }),
emptyImage: z
.string({ required_error: 'default image is required' })
.url({ message: 'default image must be a valid url' }),
opacity: z
.number()
.max(100, { message: 'opacity must be less than or equal to 100' })
.min(0, { message: 'opacity must be greater than or equal to 0' }),
shape: z.enum(['rect', 'circle'], {
invalid_type_error: 'invalid shape, must be one of: rect, circle'
})
});
export const cardValidator = z.object({
id: z.number().optional(),
name: z
.string({ required_error: 'name is required' })
.min(1, { message: 'name must be at least 1 character' }),
width: z
.number({ required_error: 'width is required' })
.finite({ message: 'width must be finite' })
.positive({ message: 'width must be positive' }),
height: z
.number({ required_error: 'height is required' })
.finite({ message: 'height must be finite' })
.positive({ message: 'height must be positive' }),
background: z
.string({ required_error: 'background is required' })
.url({ message: 'background must be a valid url' }),
has_music: z.boolean(),
is_template: z.boolean(),
is_video: z.boolean(),
price: z
.number({ required_error: 'price is required' })
.finite({ message: 'price must be finite' })
.positive({ message: 'Price must be positive' }),
published: z.boolean(),
watermark: z
.string({ required_error: 'watermark is required' })
.url({ message: 'watermark must be a valid url' }),
textBlocks: z.array(textBlockValidator),
imageBlocks: z.array(imageBlockValidator),
categories: z.array(categoryValidator).optional()
});
Same issue here. 3.19.1
is ok but 3.20.0
is causing the issue. Console stuck at [vite:dts] Start generate declaration files...
and never responses.
I've created a reproduction at https://github.com/Tanimodori/vite-dts-zod-infloop-repro
- The
buggy
branch is usingzod@3.20.0
which will stuck atdts
generation. - The
working
branch is usingzod@3.19.1
which is fine duringdts
generation.
To test with this reproduction:
git clone https://github.com/Tanimodori/vite-dts-zod-infloop-repro.git
git checkout buggy
(orgit checkout working
)pnpm i
pnpm build
Generating types from primitive types (z.number
, z.boolean
, z.string
, etc.) is fine but collection types (z.object
, z.array
, z.map
, etc.) is not workings. Seems zod
has broke the collection types in 3.20.0
mentioned in #1960.
Seems unrelated to #1960. Bug in my repro is gone in vite-plugin-dts@1.7.2
.
This seems to be working in Zod 3.21. Make sure you've enabled strict mode in your tsconfig
as well. @isaacfink can you try upgrading and report back?
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.