colinhacks / zod

TypeScript-first schema validation with static type inference
https://zod.dev
MIT License
34.26k stars 1.2k forks source link

Generating an object from schema #62

Closed KolbySisk closed 4 years ago

KolbySisk commented 4 years ago

This may not be a feature that makes sense to build, but it would be incredibly useful.

A normal workflow is to create a schema for your form state, generate a type, and then write the same object over again to use as the initial form state:

const formSchema = z.object({
  name: z.string(),
  email: z.string(),
});

type FormState= z.infer<typeof formSchema>

const initialFormState: FormState = {
  name: '',
  email: '',
 };

const [formState, setFormState] = useState<FormState>()

And now as your form grows so do these 2 objects.

I would love to be able to do something like this:

const formSchema = z.object({
  name: z.string().default(''),
  email: z.string().default(''),
});

type FormState= z.infer<typeof formSchema>

const initialForm = z.generate(formSchema);

const [formState, setFormState] = useState<FormState>(initialForm)

Currently I have a utility function I wrote that does this, it's not recursive and not very robust, but it does what I need and as a result my code is much cleaner. Everything can be updated simply by changing the Zod schema. Any thoughts on a feature like this?

cybervaldez commented 4 years ago

Looking for this too kinda similar to YUP’s cast function.

colinhacks commented 4 years ago

This will eventually be achievable with Zod transformations: #100

colinhacks commented 4 years ago

This is possible with the .default function in Zod 2: https://github.com/vriad/zod/tree/v2 (now in beta)

const formSchema = z.object({
    name: z.string().default(''),
    email: z.string().default(''),
  });

  type FormState = z.infer<typeof formSchema>;

  const initialForm = formSchema.parse({});
  console.log(initialForm);

  const [formState, setFormState] = useState<FormState>(initialForm);
andredewaard commented 1 year ago

@colinhacks Im quite late to this threat, But doesn't this defeat te purpose of validating the object afterwards?

so for example i want to create an form with name, email like above

const formSchema = z.object({
    name: z.string().default(''),
    email: z.string().email().default(''),
  });

type FormState = z.infer<typeof formSchema>;

const initialForm = formSchema.parse({});

const submitForm = async () => {
  try {
    formSchema.parse(initialForm)
    // handle submit
  } catch (e) {
    // Handle form errors
  }
}
mweel1 commented 1 year ago

Also need this, ability to create an empty object with the validation intacted.

itsyoboieltr commented 3 months ago

I also need this, as I would like to use invalid default values and .parse({}) crashes the app (as validation fails, as expected), instead of creating the default values.

Proposed API:

formSchema.create()
mrjackyliang commented 3 months ago

Was just looking for something like this as well, after realizing I am duplicating very similar code.

dzbo commented 1 month ago

How about:

formSchema.optional().parse({})
senpro-ingwersenk commented 1 week ago

Has this become a feature yet? I ran into an error with the schadcn-ui form which requires defaults and I would love to pull said defaults off my scheme.

thanks!

anthonyalayo commented 4 days ago

same thoughts as @senpro-ingwersenk , is there a solution to this today?