Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to create a reusable Input component with React & TypeScript?

It's my first attempt with React TypeScript and don't fully understand the error I'm getting when trying to build a reusable Input component. What is the TypeScript way of approaching this kind of component?

See Component & Error below:

import React, { FC, InputHTMLAttributes } from 'react';

interface InputProps extends InputHTMLAttributes<HTMLInputElement> {
    name: string;
    label: string;
    ref: string;
}

const Input: FC<InputProps> = ({ name, label, ...otherProps }, ref) => {
    return (
        <label className={styles.formLabel}>
            {label}
            <input
                className={styles.formInput}
                {...otherProps}
                name={name}
                ref={ref}
            />
        </label>
    );
};

const FormInput = React.forwardRef(Input);

export default FormInput;

Error

TypeScript error in /Users/Timmchoover/Documents/Projects/evaly/evaly-app/src/before-login/components/forms/form-input/form-input.component.tsx(25,36):
Argument of type 'FC<InputProps>' is not assignable to parameter of type 'ForwardRefRenderFunction<unknown, InputProps>'.
  Types of property 'defaultProps' are incompatible.
    Type 'Partial<InputProps> | undefined' is not assignable to type 'undefined'.
      Type 'Partial<InputProps>' is not assignable to type 'undefined'.  TS2345

    23 | };
    24 | 
  > 25 | const FormInput = React.forwardRef(Input);
       |                                    ^
    26 | 
    27 | export default FormInput;
    28 |
like image 712
Tim Avatar asked Feb 05 '26 12:02

Tim


1 Answers

I don't think FC is satisfying the type constraint here, try ForwardRefRenderFunction instead:

import React, { ForwardRefRenderFunction, InputHTMLAttributes } from 'react';

interface InputProps extends InputHTMLAttributes<HTMLInputElement> {
    name: string;
    label: string;
    ref: string;
}

const Input: ForwardRefRenderFunction<HTMLInputElement, InputProps> = ({ name, label, ...otherProps }, ref) => {
    return (
        <label className={styles.formLabel}>
            {label}
            <input
                className={styles.formInput}
                {...otherProps}
                name={name}
                ref={ref}
            />
        </label>
    );
};

const FormInput = React.forwardRef(Input);

export default FormInput;

Alternatively, you can combine Input and FormInput into one and let TypeScript infer for you:

const FormInput = React.forwardRef<HTMLInputElement, InputProps>(({ name, label, ...otherProps }, ref) => {
    ...
});


export default FormInput;
like image 134
Steven Than Avatar answered Feb 07 '26 00:02

Steven Than



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!