zod icon indicating copy to clipboard operation
zod copied to clipboard

how can I use .extend or .merge with .lazy(() => z.object({ ... }))

Open UNDERCOVERj opened this issue 2 years ago • 3 comments

as you can see,ZodType does not have extend,so how can I write the type for FormData

image

UNDERCOVERj avatar Jul 19 '22 15:07 UNDERCOVERj

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.

stale[bot] avatar Sep 17 '22 16:09 stale[bot]

Any news?

Profesor08 avatar Sep 22 '22 14:09 Profesor08

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.

stale[bot] avatar Nov 21 '22 19:11 stale[bot]

Wow, closed as stale but this is a real scenario when you have complex lazy objects that might need extending.

I'm playing with ActivityPub and it is extremely nested. Zod seemed like a perfect fit because ActivityPub implementations are all over the place, and I want some sane validation, but the nesting makes things weird.

The crux of the problem here seems to be any object that extends a lazy object must be also lazy, and I'm not sure there's a nice way of enforcing this through zod's syntax.

I ended up exposing the lazy callback as part of the object:

// Object.ts
export type ObjectType = { ... }

export function lazyObjectSchema = () => {
  ...
  return { ... }
}

export const ObjectSchema: z.ZodType<ObjectType> = z.lazy(lazyObjectSchema);


// Document.ts
import { lazyObjectSchema, ObjectType } from "./object.js";

export type Document = ObjectType & {
  ...
};

export const DocumentSchema: z.ZodType<Document> = z.lazy(() =>
  lazyObjectSchema()
    .extend({
      ...
    }),
);

Hope this is helpful to anyone else landing here with nowhere else to go.

WesSouza avatar Dec 31 '22 17:12 WesSouza