zod
zod copied to clipboard
Implement `.remap()` on `ZodObject`
The ability to modify the fields of a ZodObject schema as a function of the current fields is a much requested feature. This PR implements a new method .remap()
to enable this.
- https://github.com/colinhacks/zod/issues/2644
- https://github.com/colinhacks/zod/issues/2891
- https://github.com/colinhacks/zod/pull/2471
Given a simple initial schema...
const User = z.object({
name: z.string(),
age: z.number(),
});
...this method overwrites the existing fields as a function of the current shape
.
const ModUser = User.remap((shape) => ({
name: shape.name.optional(),
age: shape.age.nullable(),
}));
type ModUser = z.infer<typeof ModUser>;
// { name?: string; age: number | null; }
Or it can use string literals to remap keys.
const ModUser = User.remap(() => ({
name: "fullname",
age: "newage",
}));
type ModUser = z.infer<typeof ModUser>;
// { fullname: string; newage: number; }
These can be mixed as well:
const ModUser = User.remap((shape) => ({
name: "fullname",
age: shape.age.optional(),
}));
For simplicity a plain object syntax is supported as well.
const ModUser = User.remap({
name: "fullname",
age: User.shape.age.optional(),
});
type ModUser = z.infer<typeof ModUser>;
// { fullname: string; age?: number; }
Deploy Preview for guileless-rolypoly-866f8a ready!
Name | Link |
---|---|
Latest commit | 62b07154fbe9f1f007fdf922b6ecfc5d6b0c9583 |
Latest deploy log | https://app.netlify.com/sites/guileless-rolypoly-866f8a/deploys/662fffe273af260008db49c2 |
Deploy Preview | https://deploy-preview-3415--guileless-rolypoly-866f8a.netlify.app |
Preview on mobile | Toggle QR Code...Use your smartphone camera to open QR code link. |
To edit notification comments on pull requests, go to your Netlify site configuration.
Thanks for this contribution @colinhacks. Curious to know what .remap
adds vs .transform
it's not straighforward to me. Perhaps I was mistakenly using .transform
as mapper and .remap
does exactly that whereas .transform
is more field oriented ?
Curious to know what .remap adds vs .transform it's not straighforward to me
The .transform()
method lets you transform the data and returns a ZodEffects
instance. The .remap()
is for modifying the schema itself — it returns a new ZodObject
with a modified shape
(set of fields). It's a way to create variants of existing schemas.
Though this potential for confusion is interesting and worth taking into consideration. I'm not married to the name .remap()
necessarily, so if anyone has suggestions that seem less ambiguous please chime in.
So I actually think the ambiguity pointed out by @iiAku is kind of a fatal flaw. I also think .remap()
would be more valuable as a post-parse transform anyway, as opposed to something that behaves more like .extend()
. I'm going to close for now and re-evaluate.