I have a error when try to pass all props (type, placeholder, className,...etc) from my <MyTextInput />
, how could I fix it?
**
This is my code:**
<MyTextInput
label="Password:"
name="password"
placeholder="Enter your password"
className="text-pink-600"
/>
This is my custom input component:
import { FieldHookConfig, useField } from 'formik';
import React from 'react';
interface IFieldProps {
label?: string;
}
const MyTextInput: React.FC<IFieldProps & FieldHookConfig<string>> = ({
label,
...props
}) => {
const { name } = props;
const [field, meta] = useField(props);
// console.log({ field, meta, others });
return (
<div className="flex flex-col">
<label htmlFor={name}>{label}</label>
<input id={name} type="text" {...field} {...props} /> // error here...
</div>
);
};
export default MyTextInput;
** This is error:**
Type '{ ref?: LegacyRef<HTMLInputElement> | undefined; key?: Key | null | undefined; accept?: string | undefined; alt?: string | undefined; autoComplete?: HTMLInputAutoCompleteAttribute | undefined; ... 295 more ...; innerRef?: ((instance: any) => void) | undefined; } | { ...; } | { ...; }' is not assignable to type 'DetailedHTMLProps<InputHTMLAttributes<HTMLInputElement>, HTMLInputElement>'.
Type '{ ref?: LegacyRef<HTMLSelectElement> | undefined; key?: Key | null | undefined; autoComplete?: string | undefined; disabled?: boolean | undefined; ... 275 more ...; checked?: boolean | undefined; }' is not assignable to type 'DetailedHTMLProps<InputHTMLAttributes<HTMLInputElement>, HTMLInputElement>'.
Type '{ ref?: LegacyRef<HTMLSelectElement> | undefined; key?: Key | null | undefined; autoComplete?: string | undefined; disabled?: boolean | undefined; ... 275 more ...; checked?: boolean | undefined; }' is not assignable to type 'ClassAttributes<HTMLInputElement>'.
Types of property 'ref' are incompatible.
Type 'LegacyRef<HTMLSelectElement> | undefined' is not assignable to type 'LegacyRef<HTMLInputElement> | undefined'.
Type '(instance: HTMLSelectElement | null) => void' is not assignable to type 'LegacyRef<HTMLInputElement> | undefined'.
Type '(instance: HTMLSelectElement | null) => void' is not assignable to type '(instance: HTMLInputElement | null) => void'.
Types of parameters 'instance' and 'instance' are incompatible.
Type 'HTMLInputElement | null' is not assignable to type 'HTMLSelectElement | null'.
Type 'HTMLInputElement' is missing the following properties from type 'HTMLSelectElement': length, options, selectedIndex, selectedOptions, and 4 more.ts(2322)
(property) JSX.IntrinsicElements.input: React.DetailedHTMLProps<React.InputHTMLAttributes<HTMLInputElement>, HTMLInputElement>
I don't wanna do this: <input {...field} placeholder={props.placeholder} type={props.type} />
I think the problem stems from the definition of FieldHookConfig
:
export type FieldHookConfig<T> = GenericFieldHTMLAttributes & FieldConfig<T>;
with GenericFieldHTMLAttributes
defined as
export type GenericFieldHTMLAttributes =
| JSX.IntrinsicElements['input']
| JSX.IntrinsicElements['select']
| JSX.IntrinsicElements['textarea'];
Basically TypeScript is warning you that since you are using FieldHookConfig
there is always a chance the properties you receive might be select
or textarea
properties which will not be compatible with input
.
I think the best way around this is to do:
import { FieldConfig, useField } from 'formik';
import React from 'react';
interface IFieldProps {
label?: string;
}
const MyTextInput: React.FC<IFieldProps & FieldConfig<string> & JSX.IntrinsicElements['input']> = ({
label,
...props
}) => {
const { name } = props;
const [field, meta] = useField(props);
// console.log({ field, meta, others });
return (
<div className="flex flex-col">
<label htmlFor={name}>{label}</label>
<input id={name} type="text" {...field} {...props} />
</div>
);
};
export default MyTextInput;
this should narrow the type down to only access input
properties.