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

Support Zod 3.24, simplify Zod resolver, improve type performance #528

Open
wants to merge 8 commits into
base: main
Choose a base branch
from

Conversation

colinhacks
Copy link

@colinhacks colinhacks commented Dec 11, 2024

Zod creator here. This PR simplifies the Zod adapter and adds support for Zod 3.24. Should be a non-breaking change — the version range in peerDependencies is unchanged. I've verified that everything works with both 3.23.8 and 3.24.0.

Unfortunately some minor changes in 3.24 triggered an "Excessively deep and possibly infinite" TS error in this codebase, per #527. It's always a bit of a mystery as to why this error crops up.

In this case, something about the "registry" approach used by Infer and InferIn was pretty inefficient, in that it takes the input and compares it against all supported schema types (Zod, Valibot, etc), then "filters out" the never values:

type Infer<TSchema extends Schema, Keys extends keyof Registry = keyof Registry> = UnknownIfNever<
	{
		[K in Keys]: IfDefined<InferOutput<Registry[K], TSchema>>;
	}[Keys]
>;
type InferIn<TSchema extends Schema, Keys extends keyof Registry = keyof Registry> = UnknownIfNever<
	{
		[K in Keys]: IfDefined<InferInput<Registry[K], TSchema>>;
	}[Keys]
>;

For the majority of adapters, you know upfront which schema library is expected, so I added a second (optional) generic to these utilities for the scenarios (as in src/lib/adapters) where you know in advance what schema type is expected. This should dramatically improve compiler performance in the adapters where it's implemented, and as an added bonus it resolves the "Excessively deep" error.


On top of this I simplified the Zod resolver to remove some unnecessary type complexity.

Copy link

vercel bot commented Dec 11, 2024

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
superforms ✅ Ready (Inspect) Visit Preview 💬 Add feedback Dec 11, 2024 0:45am

@colinhacks colinhacks changed the title Support Zod 3.24. Improve type performance. Support Zod 3.24, simplify Zod resolver, improve type performance Dec 11, 2024

export type ZodObjectType = ZodType<Record<string, unknown>, ZodTypeDef, Record<string, unknown>>;

export type ZodObjectTypes = AnyZodObject | ZodObjectUnion<AnyZodObject> | ZodObjectType;
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The first two elements of this union are entirely subsumed by the third, so this was just adding unnecessary type complexity.


export type ZodValidation<T extends ZodObjectTypes> =
Copy link
Author

@colinhacks colinhacks Dec 11, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similarly, this isn't really doing anything useful.

  • ZodEffects<T> has the same inferred input and output types as T itself
  • ZodDefault<T> adds | undefined to the input type. I just added this directly to ZodObjectType

I'm quite confident this is a completely non-breaking change.

@ciscoheat
Copy link
Owner

Hi Colin, thank you so much for this professional adapter upgrade, what a Christmas present! :) I will add it to the next release for sure, and check the other adapters to take advantage of the new infer type parameter.

I also want to say thank you for Zod, as it's been a cornerstone in Superforms from day one, it wouldn't exist without your great library.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants