如何在打字稿中正确使用Formik中的useField钩子

时间:2020-04-07 20:48:51

标签: reactjs typescript formik

我遵循了documentation中的所有内容 并观看了Ben Awad on YouTube的教程。但是,我仍然无法正常工作。

const TextField = (props: FieldHookConfig<{}>) => {
    const [field] = useField(props);
        return (
            <div>
                <input {...field} {...props}/>
            </div>
        );
    };

我使用FieldHookConfig作为道具的类型,因为useField在Field.d.ts文件上期望使用stringFieldHookConfig。但是打字稿仍然不开心。

它在<input {...field} {...props}/>这一行中抱怨

(property) JSX.IntrinsicElements.input: React.DetailedHTMLProps<React.InputHTMLAttributes<HTMLInputElement>, HTMLInputElement>
Type '{ ref?: string | ((instance: HTMLInputElement | null) => void) | RefObject<HTMLInputElement> | null | undefined; key?: string | number | undefined; ... 289 more ...; innerRef?: ((instance: any) => void) | undefined; } | { ...; } | { ...; }' is not assignable to type 'DetailedHTMLProps<InputHTMLAttributes<HTMLInputElement>, HTMLInputElement>'.
  Type '{ ref?: string | ((instance: HTMLSelectElement | null) => void) | RefObject<HTMLSelectElement> | null | undefined; key?: string | number | undefined; ... 269 more ...; checked?: boolean | undefined; }' is not assignable to type 'DetailedHTMLProps<InputHTMLAttributes<HTMLInputElement>, HTMLInputElement>'.
    Type '{ ref?: string | ((instance: HTMLSelectElement | null) => void) | RefObject<HTMLSelectElement> | null | undefined; key?: string | number | undefined; ... 269 more ...; checked?: boolean | undefined; }' is not assignable to type 'ClassAttributes<HTMLInputElement>'.
      Types of property 'ref' are incompatible.
        Type 'string | ((instance: HTMLSelectElement | null) => void) | RefObject<HTMLSelectElement> | null | undefined' is not assignable to type 'string | ((instance: HTMLInputElement | null) => void) | RefObject<HTMLInputElement> | null | undefined'.
          Type '(instance: HTMLSelectElement | null) => void' is not assignable to type 'string | ((instance: HTMLInputElement | null) => void) | RefObject<HTMLInputElement> | null | 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)

2 个答案:

答案 0 :(得分:2)

只是为了补充上述内容,上面引用的 useField() 文档显示 label 包含在 MyTextField 属性中。为了进行这种类型的调用:

<TextField name="firstName" type="text" placeholder="Jane" label="First Name" />

添加如下界面:

interface OtherProps {
  label : string
}

然后将上面函数表达式的第一行改为:

const TextField = (props : OtherProps & FieldHookConfig<string>) => {

然后您可以通过在函数的返回块中调用 label 来引用传递的 props.label,例如:

<label htmlFor={props.id || props.name}>{props.label}</label>

答案 1 :(得分:0)

有两个问题,首先,由于类型不兼容(如错误中所指定),您无法在props元素上传播<input>变量。其次,您对FieldHookConfig的通用类型不应为{},而应为string

要解决此问题,假设您正在像这样使用<TextField>元素

<TextField
  name="firstName"
  type="text"
  placeholder="Jane"
/>

然后在您的TextField定义中,您将写

const TextField = (props: FieldHookConfig<string>) => {
  const [field] = useField(props);
  return (
    <div>
      {/* no need to pass the name field because Formik will accept
      that prop internally and pass it to the field variable */}
      <input {...field} placeholder={props.placeholder} type={props.type} />
    </div>
    );
};