You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I've been thinking about how to make coerce something more powerful and generic than what it is right now and I think I found an elegant solution. Not knowing zod codebase perfectly (I read a big part of it though) I might be missing things that would make this impossible. But I think it should work.
1st, add to every zod schema a schema.constructWith(inputSchema) method (that name can obviously be changed, I'm not sure it is good) that would satisfy the followings:
inputSchemaREQUIRES a compatible OutputType type with the schema's InputType
That method would return a similarly typed ZodSchema except for its InputType that would be changed to the same one as the one of inputSchema
The returned schema would basically be the same schema but constructed with the inputSchema in its def object
Change the parse method to run it on inputSchema.parse(val) instead of val directly when there is one
2nd add a schema.coerce(transformFn, outputSchema) method to every zod schema that would basically just return outputSchema.constructWith(schema.transform(transformFn)).
Those changes would allow to implement existing coerce tooling more easily:
zod.coerce.number=z.string().or(z.number())// that might not be enough to put Number only there, but it keeps things simple.coerce(Number,z.number());// or, more complex but more efficient:zod.coerce.number=z.number().constructWith(z.number().or(z.string().transform(Number)));// ZodNumber would need to be parameterized with its input type now// eg: ZodNumber<Input = number> extends ZodType<number, ZodNumberDef, Input> {}// zod.coerce.number would be defined as a ZodNumber<string | number>
I think that would also allow to completely deprecate z.preprocess() that would be better served by using .coerce() or .constructWith() (it could always be simulated using z.unknown().coerce(), the only difference being that the resulting schema would be "better" typed).
Some very cool uses for this would be to create some generic schemas representing more complex things that can still be used in a very intuitive way after that:
// duration.tsimportparseDurationfrom"parse-duration";exportduration=z.number().or(z.string().min(1)).coerce((val: string|number)=>typeofval==="string" ? parseDuration : val,z.number());// ZodNumber<string | number> here too// example.tsimport{duration}from"./duration.js";constrequestTimeout=duration.int("do not support µs").min(1_000,"1s minimum timeout");// ...requestTimeout.parse("20s");// OK => 20_000requestTimeout.parse("200ms");// fails with "1s minimum timeout"requestTimeout.parse(10_000);// OK => 10_000requestTimout.parse(10_000.25);// fails with "do not support µs"
The text was updated successfully, but these errors were encountered:
Hi!
I've been thinking about how to make
coerce
something more powerful and generic than what it is right now and I think I found an elegant solution. Not knowingzod
codebase perfectly (I read a big part of it though) I might be missing things that would make this impossible. But I think it should work.1st, add to every zod schema a
schema.constructWith(inputSchema)
method (that name can obviously be changed, I'm not sure it is good) that would satisfy the followings:inputSchema
REQUIRES a compatibleOutputType
type with the schema'sInputType
ZodSchema
except for itsInputType
that would be changed to the same one as the one ofinputSchema
schema
but constructed with theinputSchema
in its def objectinputSchema.parse(val)
instead ofval
directly when there is one2nd add a
schema.coerce(transformFn, outputSchema)
method to every zod schema that would basically just returnoutputSchema.constructWith(schema.transform(transformFn))
.Those changes would allow to implement existing coerce tooling more easily:
I think that would also allow to completely deprecate
z.preprocess()
that would be better served by using.coerce()
or.constructWith()
(it could always be simulated usingz.unknown().coerce()
, the only difference being that the resulting schema would be "better" typed).Some very cool uses for this would be to create some generic schemas representing more complex things that can still be used in a very intuitive way after that:
The text was updated successfully, but these errors were encountered: