'Typescript interface extends two component types
So this will output an <input> element - everything works perfectly:
interface InputProps extends React.InputHTMLAttributes<HTMLInputElement> {
error?: FieldError;
icon?: string;
id: string;
register?: UseFormRegisterReturn;
}
const StyledInputComponent = styled.input`
...
`
const MyComponent = ({
error,
icon,
id,
register,
onChange,
...props
}: InputProps) => {
return (
<StyledInputComponent
hasError={!!error}
id={id}
onChange={onChange}
placeholder={placeholder}
type={type}
{...register}
{...props}
/>
});
};
I now need to be able to have the consuming component choose between an <input> and a <textarea>.
The problem I have is that (I think) I need to extend the interface further like this:
interface InputProps extends React.InputHTMLAttributes<HTMLInputElement>, React.InputHTMLAttributes<HTMLTextAreaElement> {
error?: FieldError;
icon?: string;
id: string;
inputType?: "input" | "textarea";
register?: UseFormRegisterReturn;
}
And I'm just using the new inputType prop to switch between outputted components:
{ inputType === "input" &&
<StyledInputComponent
hasError={!!error}
id={id}
onChange={onChange}
placeholder={placeholder}
type={type}
{...register}
{...props}
/>
}
{ inputType === "textarea" &&
<StyledTextAreaComponent
hasError={!!error}
id={id}
onChange={onChange}
placeholder={placeholder}
rows={4}
{...register}
{...props}
/>
}
However, trying to extend the interface for both an <input> and a <textarea> has lead to numerous errors, all along these lines:

What's the right way to go about resolving this?
Solution 1:[1]
I've tried your solution, but I have some problems when returning an input text or a textarea
function MyComponent<T extends 'input' | 'textarea'>(props: InputProps<T>) {
const {inputType, ...rest} = props;
if (inputType === "input") {
return <input
// ^error
type={"text"}
{...rest}
/>
}
if (inputType === "textarea") {
return <textarea
// ^error
{...rest}
/>
}
return null
}
This are the returned errors:
Type '{ type: "text"; } & Omit<InputProps<T>, "inputType">' is not assignable to type 'DetailedHTMLProps<InputHTMLAttributes<HTMLInputElement>, HTMLInputElement>'.
Type '{ type: "text"; } & Omit<InputProps<T>, "inputType">' is not assignable to type 'ClassAttributes<HTMLInputElement>'.
Types of property 'ref' are incompatible.
Type 'InputProps<T>["ref"] | undefined' is not assignable to type 'LegacyRef<HTMLInputElement> | undefined'.
I can solve the problem if the rest variable is casted to JSX.IntrinsicElements["input"] or JSX.IntrinsicElements["textarea"]... but I don't think is the best solution... Any alternative?
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | mtz |
