React Hook Form Property 'type' is missing in type 'Merge<FieldError, FieldErrorsImpl<DeepRequired<any>>>' but required in type 'FieldError'

Viewed 338

I'm building an Next.js application using TypeScript, TailwindCSS, ReactHookForm and Yup.

Everything is working fine, it validates, throws and displays the error as expected, but I'm getting a typing error when using ReactHookForm to throw errors and passing them to my Input component.

My code:

  const {
    register,
    handleSubmit,
    formState: { errors },
    setValue
  } = useForm({ resolver: yupResolver(signUpFormSchema) });

  return (
    <>
        <form
          onSubmit={handleSubmit(handleSubmitSignUpForm)}
          className="container flex flex-wrap items-center justify-center gap-4 px-4 py-6 rounded-md group bg-gray-150"
        >
          <h1 className="text-2xl font-bold tracking-wide uppercase text-blue">
            Inputs
          </h1>

          <Input
            id="name"
            name="name"
            placeholder="Seu nome Completo"
            label={
              <>
                Seu <strong>Nome</strong>
              </>
            }
            error={errors.name}
            {...(register('name'),
            {
              onChange: (e) => {
                setValue('name', maskName(e.target.value));
              }
            })}
          />

          <Button type="submit">Enviar</Button>
        </form>
    </>
  );

Here's my Input component:

import { forwardRef } from 'react';
import { FieldError } from 'react-hook-form';

import { CheckIcon } from 'assets/Icons';

import styles from './styles.module.css';

type InputProps = {
  variant?: 'default' | 'search';
  name: string;
  label?: React.ReactNode;
  error?: FieldError;
} & React.InputHTMLAttributes<HTMLInputElement>;

const VariantMap = {
  default: styles.default,
  search: styles.search
};

const InputBase: React.ForwardRefRenderFunction<
  HTMLInputElement,
  InputProps
> = ({ variant = 'default', name, label, error = null, ...rest }, ref) => {
  const defaultClassName = styles.root;
  const className = [defaultClassName, VariantMap[variant]];

  return (
    <div className="flex flex-col w-full gap-1.25 relative">
      {label && (
        <label htmlFor={name} className={styles.label}>
          {label}
        </label>
      )}
      <input
        name={name}
        id={name}
        ref={ref}
        {...rest}
        className={className.join(' ')}
      />
      <CheckIcon className="absolute transform translate-y-1/2 bottom-6 right-5" />
      {!!error && <span>{error.message}</span>}
    </div>
  );
};

export const Input = forwardRef(InputBase);

This is the error I'm getting: enter image description here

1 Answers

this seems to be an issue with react-hook-form types. Since you already have a custom implementation of a Input component I would recommend using useController to fetch the field error instead of getting it through the errors object from useForm.

To use that hook, all you have to do is send an object with field registered name and react-hook-form's controller. Doing that your error attribute will have the correct FieldError | undefined type.

import { useController } from 'react-hook-form'

function TextField({ label, controller }) {
  const { fieldState: { error } } = useController({ name, controller })
  ...
}

btw, you omit the controller if you're already using FormProvider

Related