zod icon indicating copy to clipboard operation
zod copied to clipboard

Propose feature`.defer()` to support lazy parsing

Open SnowSuno opened this issue 8 months ago • 0 comments

I propose a new feature defer to support lazy parsing, which is requested on #2060.

I think this feature would have pretty much use cases such as:

  • Only parse the needed fields and prevent unused fields breaking the application.
  • Defer parsing of expensive large schemas.
  • And more...

What it does

You can mark a subpart of a schema as 'deferred' using .defer()

The parsing of a schema which is marked 'deferred', is skipped during the parsing, and outputs a function that can be called to parse the input laterwise where the schema is actually used.

const schema = z.object({
  foo: z.string(),
  bar: z.string().defer(),
})

const parsed = schema.parse({ foo: "foo", bar: "bar" });  // bar is not parsed here

parsed.foo
parsed.bar() // bar is parsed here

Interface

// standalone
z.defer(z.string());

// method
z.string().defer();

// can be combined with other effects
z.string().transform(val => val.length).defer();

Additional helper methods

Since the realworld usage would require scenarios like 'defer all props of an object', I also propose a helper method .deferProps() in ZodObject.

(Just like .partial() in .optional())

I don't think .deferProps() is the best naming of the functionality. I'm open for suggestions.

z.object({
  foo: z.number(),
  bar: z.string(),
}).deferProps();

// same as 
z.object({
  foo: z.number().defer(),
  bar: z.string().defer(),
});

As .partial() accepts a mask to mark the fields to be optional. .deferProps() also does.

z.object({ ... }).deferProps({ foo: true })  // defer prop 'foo' only

WIP

The docs and more exhaustive test cases is a work in process. I plan to work on it after discussions about this new feature request.

SnowSuno avatar Jun 06 '24 12:06 SnowSuno