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 |Advertisement
Answer
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;