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;