react-hook-form: errors inferred type is incorrect when using yup notRequired

Having a schema like this

const schema = yup.object().shape({
smtpInfo: yup
    .object({
      host: yup.string().required(),
      port: yup.string().required(),
      user: yup.string().required(),
      password: yup.string().required(),
      secure: yup.boolean(),
    }).notRequired()

when inferring the form data type

type FormData = yup.InferType<typeof schema>;

the errors type returning from

const { handleSubmit, errors, formState, register, reset, watch } = useForm<
    FormData
  >({
    validationSchema: schema,
  });

is incorrect

errors.smtpInfo returns a FieldError | undefined whereas removing the notRequired from the schema it returns a NestDataObject<{...}, FieldError> | undefined

Expected behavior The returned type should still be the nested object with all the fields, since it could be undefined one can add a check for that.

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Comments: 17 (7 by maintainers)

Most upvoted comments

I don’t think we are supporting schema type infer on V5, @kotarella1110 will this be solved on V6?

Yes. This will be fixed in V6. https://codesandbox.io/s/ts-react-hook-form-validated-submit-5yoj7?file=/src/App.tsx

@bluebill1049 Should I apply this fix to V5?

@krish-dev The last version working is 0.28.3

OK so I guess I will have to do a mix between the 2 😕. Something Like this

type FormData = yup.InferType<typeof validationSchema> & {
  smtpInfo?:
    | {
        host: string;
        port: number;
      }
    | undefined;
  testObject: NestedValue<{
    test: string;
  }>;
};

Thanks @kotarella1110 for the response

@tafelito You cannot use yup.InferType if it contains object or array value in FormData. You have to define the type yourself using NestedValue.

import { NestedValue } from 'react-hook-form';

type FormData = {
    smtpInfo?: {
        host: string;
        port: number;
    } | undefined;
    description: string;
    testObject: NestedValue<{
        test: string;
    }>;
}

I don’t think we are supporting schema type infer on V5, @kotarella1110 will this be solved on V6?

Yes. This will be fixed in V6. https://codesandbox.io/s/ts-react-hook-form-validated-submit-5yoj7?file=/src/App.tsx

@bluebill1049 Should I apply this fix to V5?

awesome! no, let’s roll this out in V6. 👍

I’m using version 6.0.8 I have a very simple login form that does not have a nested object or array. However, I’m getting the same error

Type 'InnerInferType<Shape<object | undefined, { email: string; password: string; }>>' does not satisfy the constraint 'Record<string, any>'.
  Type 'undefined' is not assignable to type 'Record<string, any>'.

Screenshot 2020-07-22 at 3 22 48 PM

Here is my simple login form code.

import React from 'react';
import {useForm} from 'react-hook-form';
import {yupResolver} from '@hookform/resolvers';
import * as yup from 'yup';

const loginSchema = yup.object().shape({
  email: yup.string().defined().email(),
  password: yup.string().defined(),
});

const initialValues = {email: '', password: ''};

type LoginInput = yup.InferType<typeof loginSchema>;

const LoginForm = () => {
  const {register, handleSubmit} = useForm<LoginInput>({
    defaultValues: initialValues,
    resolver: yupResolver(loginSchema),
  });

  const onSubmit = (data: LoginInput) => {
    console.log(data);
  };

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <label>Email</label>
      <input type="email" name="email" ref={register} />
      <label>Password</label>
      <input type="password" name="password" ref={register} />
      <input type="submit" />
    </form>
  );
};

export default LoginForm;