2

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 |

2 Answers 2

10

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;
Sign up to request clarification or add additional context in comments.

1 Comment

That solved it, thanks! Didn't know about the ForwardRefRenderFunction. Guess I need to spend some more time in the docs. Appreciate the help!
0
const Input = React.forwardRef<React.HTMLInputElement, InputProps>({ name, label, ...otherProps }, ref) => {
    return (
        <label className={styles.formLabel}>
            {label}
            <input
                className={styles.formInput}
                {...otherProps}
                name={name}
                ref={ref}
            />
        </label>
    );
};

2 Comments

And that will remove the type's. You might have not noticed, but the OP is also using Typescript..
Sorry, i edited my answer now i think i will satisfy your condition and again sorry there was a typing mistake now i corrected

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.