Pass schema to function and it returns infer-ed type of schema
Hey, thank you so much for this library, it is awesome!!
I try to achieve validation function for http responses, that could:
- accept response schema as argument
- validate response against schema
- return validated response or throw an error
Below is my maximum I could create :sweat_smile: and it works in simple cases.
async function requestWithValidate<T>(
httpCall: () => Promise<unknown>,
schema: z.ZodSchema<T>
): Promise<T> {
try {
const response = await httpCall();
return schema.parse(response);
} catch (e) {
if (e instanceof ZodError) {
e = e.format();
}
throw e;
}
};
However, when I pass schema that contains ZodEffect(schema field with pre-processor for example) I have type incompatibility.
I have it for Date fields and for them I get Type 'unknown' is not assignable to type 'Date'
Pre-processor:
const stringToDateConvert = z.preprocess((arg) => {
if (typeof arg === 'string' || arg instanceof Date) {
return new Date(arg);
}
}, z.date());
Example schema:
z.object({
id: z.number(),
date: stringToDateConvert.nullable(),
}).nullable();
Could you please help with setup of generics for this function that could work even with any Zod type?
I found workaround to infer type from _type like this:
export = async function requestWithValidate
<T extends { parse(data: unknown, params?: Partial<ParseParams>): unknown; _type: unknown }>
(httpCall: () => Promise<unknown>, schema: T): Promise<T['_type']> {
try {
const response = await httpCall();
return schema.parse(response);
} catch (e) {
if (e instanceof ZodError) {
e = e.format();
}
throw e;
}
};
@colinhacks , mb we could add this into doc? I think my case faced quite often for others as well
Is this what you are looking for?
async function requestWithValidate<Schema extends z.ZodTypeAny> (
httpCall: () => Promise<unknown>,
schema: Schema
): Promise<z.infer<Schema>> {
try {
const response = await httpCall()
return schema.parse( response )
} catch ( e ) {
if ( e instanceof z.ZodError ) {
e = e.format()
}
throw e
}
}