Replies: 3 comments 7 replies
|
+1 here.
const schema = z.object({
amount: z.number().nullable().transform((v) => v ?? 0)
});
type FormFields = z.input<typeof schema>;
// { amount: number | null | undefined }
type FormPayload = z.output<typeof schema>;
// { amount: number }
const form = useForm<FormFields, FormPayload>({
resolver: zodResolver(schema),
});
const handleSubmit = form.handleSubmit(
function onValid (payload) {
// { amount: number }
}
);At present, the only resolution I know of (as @Svish suggests) is to hard-assert it in the submit handler.... const handleSubmit = form.handleSubmit(
function onValid (values) {
const payload = values as unknown as FormPayload;
// { amount: number }
}
); |
|
Also just a hack, but maybe helpful for someone. I took another approach: Instead of allowing Here's a small helper to make one or more fields of your schema export type OmitStrict<T, K extends keyof T> = T extends unknown
? Pick<T, Exclude<keyof T, K>>
: never
export type Undefinable<T> = T | undefined
/**
* This is a hack for a schema that needs an `undefined` field on the input which is not allowed to be `undefined` for the output.
* This situation e.g. exists on fields of an initial form to create something. e.g. we don't want to have a category selected when
* a new post is created, so the field is `undefined`.
*/
export type FormDefaultValuesUndefinable<
TSchema extends z.ZodTypeAny['_output'],
TKeyToOverwrite extends keyof TSchema
> = OmitStrict<TSchema, TKeyToOverwrite> & {
[K in keyof TSchema as TKeyToOverwrite]: Undefinable<TSchema[TKeyToOverwrite]>
}In this example I expect a type SchemaCreatePost = z.infer<typeof schemaCreatePost>
const defaultValuesCreate: FormDefaultValuesUndefinable<
SchemaCreatePost,
'categoryId'
> = { title: '', categoryId: undefined } |
|
To answer your original question. You can do this now: const { handleSubmit } = useForm<InputType, unknown, OutputTypeAfterValidation>({
// ...
}) |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Take the following schema written using
yup:I now want to use these types with
useForm:The issue is that I have to substitute
???for eitherYupValuesorYupValid. Picking the first allows me to set the default value tonull, but gives me the wrong type in my submit-handler. Picking the second gives me the correct data type in my submit-handler, but doesn't allow me to usenullas a default value...Is there a way to do this correctly typewise? I assume the type being passed into the submit-handler will have been through the yup resolver and therefore will be valid and match the
YupValidtype, so I suppose I could "cast" it with anas YupValid, but I really don't like usingasif I can avoid it.There's a similar concept with
zod, which is actually calledinputandoutput:Here it would similarly be great if there was a way to get the correct type in the correct places when using
react-hook-form.All reactions