Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Strip checks and effects #3547

Open
bkdiehl opened this issue Jun 5, 2024 · 0 comments
Open

Strip checks and effects #3547

bkdiehl opened this issue Jun 5, 2024 · 0 comments

Comments

@bkdiehl
Copy link

bkdiehl commented Jun 5, 2024

Given a schema with many checks and/or effects, I need to be able to parse an object without using any of the checks or effects. Take the following contrived schema

const schema = z.object({
  name: z.string().nonempty().max(6).refine((val) => val !== 'bob'),
  hobbies: z.object({ name: z.string().nonempty() }).array().min(1),
});

The schema is defined, I don't want to re-write it. I don't want to have to declare a base schema without checks/effects and extend it with checks/effects. I want to strip the checks and effects so that the resulting schema looks like this

const schema = z.object({
  name: z.string(),
  hobbies: z.object({ name: z.string() }).array(),
});

I've tried doing this manually, but I can't strip the checks and effects without modifying the original schema. I would have to be able to deep clone the schema. My hacky attempt looks like this

function stripChecksAndEffects<TSchema extends ZodTypeAny>(schema: TSchema): TSchema {
  if (schema instanceof ZodEffects) return stripChecksAndEffects(schema._def.schema);
  if (schema instanceof ZodArray)
    return z.array(stripChecksAndEffects(schema.element)) as unknown as TSchema;
  if (schema instanceof ZodObject) {
    let dictionary = z.object({});
    for (const [key, value] of Object.entries(schema.shape)) {
      dictionary = dictionary.extend({ [key]: stripChecksAndEffects(value as any) });
    }
    return dictionary as unknown as TSchema;
  }
  if (schema._def.innerType) {
    schema._def.innerType = stripChecksAndEffects(schema._def.innerType);
  }
  if (schema._def.checks) schema._def.checks = [];
  return schema;
}

const strippedSchema = stripCheckAndEffects(schema)

While this does successfully strip the checks and effects, the input schema is also modified. Hence the need for a deep clone method. Alternatively, it would be even better if, similar to .deepPartial, there were methods like .stripEffects and .stripChecks that could provide this functionality.

My particular use case is letting me validate unkown json to set default form data. As long as the unkown json is in the correct shape, the validation would pass and the form populated. The more important and complex validation wouldn't occur until the form is submitted.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant