I've searched through the documentation but find no solution for this case. I've got the following schemas.
const RelationSchema = z.object({
guid: z.string(),
createdDate: z.preprocess(castToDate, z.date()),
modifiedDate: z.preprocess(castToDate, z.date()).nullable(),
name: z.string(),
publicationtype: z.string(),
contentType: z.string(),
});
export const NobbRelationsSchema = z.array(NobbRelationSchema);
When parsing an array with NobbRelationsSchema.parse()
I sometimes get back name
as undefined. In these cases I would like Zod not to throw an error, but instead just remove that element and continue with the rest. A kind of filtering.
The option I see is to use safeParse
and set name
as optional and filter out these afterwards. However, it messes up the TypeScript type checking later in code, as name
should always be set for valid elements.
The option I see is to use
safeParse
and set name as optional and filter out these afterwards.
I think the simplest thing to do would be to add something special rather than using z.array
: safe parse an unknown array and filter that. For example:
import { z } from 'zod';
// -- snip your code here --
type NobbRelation = z.TypeOf<typeof RelationSchema>;
function parseData(data: unknown) {
// First parse the shape of the array separately from the elements.
const dataArr = z.array(z.unknown()).parse(data);
// Next parse each element individually and return a sentinal value
// to filter out. In this case I used `null`.
return dataArr
.map(datum => {
const parsed = RelationSchema.safeParse(datum);
return parsed.success ? parsed.data : null;
})
// If the filter predicate is a type guard, the types will be correct
.filter((x: NobbRelation | null): x is NobbRelation => x !== null);
}
For the most part this shouldn't limit your options. If you have other limitations you want to impose on the array
, like a maximum length, you can do that when you process the unknown array.
If you have additional post processing you would like to do with transform
, you could do that with a step after the filter
.
If you want to have the type for NobbRelationsSchema
you could derive that as:
type NobbRelations = NobbRelation[]; // Or just write this inline