zod icon indicating copy to clipboard operation
zod copied to clipboard

z.pick() with z.partial() ignores z.pick() for zod mini.

Open JoshuaKirby88 opened this issue 7 months ago • 1 comments

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.

JoshuaKirby88 avatar Apr 12 '25 10:04 JoshuaKirby88

Solution for now is to add ".clone()":

z.partial(z.pick(userSchema, { id: true, email: true }).clone(), { id: true })

JoshuaKirby88 avatar Apr 12 '25 11:04 JoshuaKirby88

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.

colinhacks avatar May 15 '25 07:05 colinhacks

🙏

JoshuaKirby88 avatar May 15 '25 07:05 JoshuaKirby88