zod
zod copied to clipboard
Allow array to return only valid items and not fail whole array
When validating an array, I would like to only return the valid items in an array and not fail if one item fails.
This is a very basic example
const schema = z.object({
arr: z.array(z.number())
})
const result = schema.safeParse({arr: [1,2,"3"]})
I would like this to return only the valid items
arr: [1,2]
I tried using refine
on the array, but it seems to only be called when the array validates correctly. Is there a way to do this, or is this something you'd be willing to support?
Hi @bmeverett,
I don't know if Zod maintainers will support this specific claim in the lib, but you can build a custom validator that uses error.issues
to filter it manually based on invalid properties/items issued by zod.
I've implemented something like that just as a proof of concept:
const validator = (schema: z.Schema<any, any>) => (data: object) => {
const response = schema.safeParse(data);
if (response.success === false) {
const errorPaths = response.error.issues.map((issue) => issue.path);
let filteredData = data;
errorPaths.forEach(
(error) => (filteredData = filterByPath(filteredData, error))
);
return filteredData;
}
return data;
};
const result = validator(schema)(input);
The most difficult part is the filterByPath()
function, which I've got something that works but maybe it's not perfect in performance terms and maybe does not cover all cases.
I would suggest you develop your own for your needs. For reference, you can see my implementation here in StackBlitz.
@bmeverett Is this what you're looking for?
const schema = z.object( {
arr: z.any().array().transform(
arr => arr.map( item =>
z.number().safeParse( item ).success ? item : undefined
).filter( Boolean )
),
} )
console.log( schema.parse( { arr: [ 1, 2, '3' ] } ) ) // { arr: [ 1, 2 ] }
Thanks @JacobWeisenburger and @lucassarcanjo I think I can work with these.