Home > Enterprise >  React/Typescript creating custom input forwardRef
React/Typescript creating custom input forwardRef

Time:09-26

I have the following component

interface IInputProps extends React.HTMLProps<HTMLInputElement> {}

const Input: React.FunctionComponent<IInputProps> = React.forwardRef((props, ref: React.ForwardedRef<HTMLInputElement>) => {
return <input ref={ref} />;
});

I want to create a custom input where you can forward a ref to it, however I'm getting the error

Type 'ForwardRefExoticComponent<Pick<IInputProps, "key" | "accept" | "acceptCharset" | "action" | "allowFullScreen" | "allowTransparency" | "alt" | "as" | "async" | "autoComplete" | "autoFocus" | ... 348 more ... | "onTransitionEndCapture"> & RefAttributes<...>>' is not assignable to type 'FunctionComponent<IInputProps>'.
Types of parameters 'props' and 'props' are incompatible.
Type 'PropsWithChildren<IInputProps>' is not assignable to type 'Pick<IInputProps, "key" | "accept" | "acceptCharset" | "action" | "allowFullScreen" | "allowTransparency" | "alt" | "as" | "async" | "autoComplete" | "autoFocus" | ... 348 more ... | "onTransitionEndCapture"> & RefAttributes<...>'.
    Type 'HTMLProps<HTMLInputElement> & { children?: ReactNode; }' is not assignable to type 'RefAttributes<HTMLInputElement>'.
    Types of property 'ref' are incompatible.
        Type 'LegacyRef<HTMLInputElement> | undefined' is not assignable to type 'Ref<HTMLInputElement> | undefined'.
        Type 'string' is not assignable to type 'Ref<HTMLInputElement> | undefined'.ts(2322)

What is the reason for this?

CodePudding user response:

You are using HTMLProps that extends ClassAttributes which define ref attribute as LegacyRef (string | Ref<T> | undefined).

On the opposite side you have forwardRef that returns a component for which the ref attribute is typed as Ref<T> | undefined.

So the ref attribute types are not compatible.

I recommend using:

import React from 'react'

interface IInputProps extends React.ComponentProps<'input'> {}

const MyInput = React.forwardRef<HTMLInputElement, IInputProps>((props, ref) => {
  return <input ref={ref} />;
});

And also I tend to avoid using React.FunctionComponent<Props> (see https://react-typescript-cheatsheet.netlify.app/docs/basic/getting-started/function_components).

  • Related