I am trying to validate and reshape the following object:
{ title: "My title", body: "My body", category: { id: 1, name: "My category" }
I would like to output the following shape after validation:
{ title: "My title", body: "My body", categoryId: 1 }
Here is my schema:
const ArticleSchema = z.object({
title: z.string().min(5),
body: z.string().min(5),
category: z
.object({
id: z.number().int(),
name: z.string(),
})
.transform((input) => input.id),
});
Zod's transform
method can modify the shape of the value, but I would also like to modify the name of the key to be categoryId
instead of category
.
ArticleSchema.parse(data)
outputs this:
{ title: "My title", body: "My body", category: 1 }
I also tried this:
const ArticleSchema = z.object({
title: z.string().min(5),
body: z.string().min(5),
category: z
.object({
id: z.number().int(),
name: z.string(),
})
.transform((input) => ({ categoryId: input.id }),
});
But it outputs this:
{ title: "My title", body: "My body", category: { categoryId: 1 } }
Is this possible?
This is possible, but it may lead to a good amount of duplication (if done in a naive way) since you cannot simply merge the values and add in the field you want without keeping the old field around.
What you are looking for can be achieved by moving the transform up a level to the outermost object. The
categoryId
key belongs to that object so that is the place you need to transform.