zod
zod copied to clipboard
z.pick() with z.partial() ignores z.pick() for zod mini.
import * as z from "@zod/mini"
const userSchema = z.interface({ id: z.number(), email: z.email(), name: z.string() })
type UserSchema = z.infer<typeof userSchema>
// UserSchema = {
// id: number;
// email: string;
// name: string;
// }
const pickedUserSchema = z.pick(userSchema, { id: true, email: true })
type PickedUserSchema = z.infer<typeof pickedUserSchema>
// PickedUserSchema = {
// id: number;
// email: string;
// }
const partialPickedUserSchema = z.partial(pickedUserSchema, { id: true })
type PartialPickedUserSchema = z.infer<typeof partialPickedUserSchema>
// PartialPickedUserSchema = {
// id?: number | undefined;
// email: string;
// }
const wrongSchema = z.partial(z.pick(userSchema, { id: true, email: true }), { id: true })
type WrongSchema = z.infer<typeof wrongSchema>
// WrongSchema = {
// id?: number | undefined;
// email: string;
// name: string;
// }
partialPickedUserSchema and wrongSchema should be the same, but they are different. When defining the pickedUserSchema inside z.partial(), it ignores z.pick(), and is adding back the name field.
Solution for now is to add ".clone()":
z.partial(z.pick(userSchema, { id: true, email: true }).clone(), { id: true })
Smart fix with .clone().
This is an interesting limitation of TS inference. I've found a workaround so .clone() shouldn't be necessary in latest betas.
🙏