With a complex Zod object, I would like to recursively search for a property someProp
and remove it wherever it exists, possibly using .omit({ someProp: true })
. Here is an attempt that does not work...
function removeSomeProp<T extends ZodRawShape>(obj: T): T {
const result: any = {};
Object.keys(obj).forEach((key) => {
const value = obj[key];
if (value instanceof ZodObject) {
result[key] = removeSomeProp(value.shape);
} else {
result[key] = value;
}
});
return z.object(result).omit({ someProp: true }) as unknown as T;
}
Here is the solution I came up with... Note that once it find a someProp
property, it no longer recurses down that branch. This also makes a few assumptions about the shape of the ZodObject.
function removeSomeProp(schema: ZodTypeAny): ZodTypeAny {
if (schema instanceof ZodObject) {
if (schema.shape["someProp" as keyof typeof schema.shape]) {
return schema.omit({ someProp: true });
}
const newObj: any = {};
Object.keys(schema.shape).forEach((key) => {
newObj[key as keyof typeof newObj] = removeSomeProp(schema.shape[key as keyof typeof schema.shape]);
});
return z.object(newObj);
}
if (schema instanceof ZodOptional) {
// eslint-disable-next-line no-underscore-dangle
return removeSomeProp(schema._def.innerType);
}
if (schema instanceof ZodArray) {
return removeSomeProp(schema.element);
}
return schema;
}