Z
Zod•2mo ago
Z4RM

Z4RM - Hello! I'm going to write a fullstack ap...

Hello! I'm going to write a fullstack application, and for types consistency between my backend and frontend, I'm looking at Zod and implementing it in my app. However, I'm running into an issue: I want to include the error object returned from the parse method, but I don't find how I can "include" it in a z.object. I'm not sure if what I say is very clear, so here is an explanation in code:
// Credentials.ts

import { z, type SafeParseReturnType } from 'zod';

const Credentials = z.object({
email: z.string().regex(/^[\w-.]+@([\w-]+\.)+[\w-]{2,4}$/),
password: z.string().min(1)
});

export type Credentials = z.infer<typeof Credentials>;

export function parseCredentials(data: unknown): SafeParseReturnType<Credentials, Credentials> {
return Credentials.safeParse(data);
}
// Credentials.ts

import { z, type SafeParseReturnType } from 'zod';

const Credentials = z.object({
email: z.string().regex(/^[\w-.]+@([\w-]+\.)+[\w-]{2,4}$/),
password: z.string().min(1)
});

export type Credentials = z.infer<typeof Credentials>;

export function parseCredentials(data: unknown): SafeParseReturnType<Credentials, Credentials> {
return Credentials.safeParse(data);
}
// LoginResponse.ts

import { z } from 'zod';
import { type Credentials, parseCredentials } from './Credentials';

const LoginResponse = z.union([
z.object({
code: z.literal(200),
message: z.literal('Success'),
data: z.object({
token: z.string()
})
}),
z.object({
code: z.literal(400),
message: z.literal('Invalid credentials'),
error: // I would like that this property is of type `SafeParseReturnType<Credentials>` (from `parseCredentials(<credentials>).error`)
})
]);

export type LoginResponse = z.infer<typeof LoginResponse>;

export function parseLoginResponse(data: unknown) {
return LoginResponse.safeParse(data);
}
// LoginResponse.ts

import { z } from 'zod';
import { type Credentials, parseCredentials } from './Credentials';

const LoginResponse = z.union([
z.object({
code: z.literal(200),
message: z.literal('Success'),
data: z.object({
token: z.string()
})
}),
z.object({
code: z.literal(400),
message: z.literal('Invalid credentials'),
error: // I would like that this property is of type `SafeParseReturnType<Credentials>` (from `parseCredentials(<credentials>).error`)
})
]);

export type LoginResponse = z.infer<typeof LoginResponse>;

export function parseLoginResponse(data: unknown) {
return LoginResponse.safeParse(data);
}
So, my question is: here is a way to do this, and if yes, how? Thank you by advance! 😄
Solution:
You could use z.custom for this
Jump to solution
9 Replies
Solution
janglad
janglad•2mo ago
You could use z.custom for this
Z4RM
Z4RMOP•2mo ago
Okay, so I imagine I'm obliged to create by myself a validator. Thanks in any case!
janglad
janglad•2mo ago
how do you mean? I mean I guess you mean you want to parse the error but my question is why 😄 if you're not going to trust the error coming out of Zod why trust the parsing it's doing
Z4RM
Z4RMOP•2mo ago
No I mean like backend could send an error which is not a ZodFormattedError<Credentials>
janglad
janglad•2mo ago
In that case just type it as such, probably best using a discriminated union like {code: "INPUT_PARSING" , error: z.ZodError...} | {code: "UNCAUGHT", error: unknown} but also FYI if this is for typing a back end endpoint, you can't really serialise Errors (and shouldn't really try to either as they have info like the stack trace that shouldn't make it to the client)
Z4RM
Z4RMOP•2mo ago
You mean ZodFormattedError contains stack trace?
janglad
janglad•2mo ago
aah shit sorry completely misread that no formatted error is fine!
Z4RM
Z4RMOP•2mo ago
No it's my fault, in my orginial message I write SafeParseReturnType<Credentials>
janglad
janglad•2mo ago
yea that one would have a stack trace if I have it right
Want results from more Discord servers?
Add your server