You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在TypeScript中正确使用Formik的useField?自定义组件传参报错修复

解决Formik自定义输入组件的TypeScript类型错误

问题背景

给自定义组件<MyTextInput/>传递type、placeholder、className等props时触发TypeScript类型错误,不想通过逐个指定props的方式修复,需要通用解决方案。

调用代码

<MyTextInput
 label="Password:"
 name="password"
 placeholder="Enter your password"
 className="text-pink-600"
/>

自定义组件代码

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);

  return (
    <div className="flex flex-col">
      <label htmlFor={name}>{label}</label>
      <input id={name} type="text" {...field} {...props} /> {/* 此处报错 */}
    </div>
  );
};

export default MyTextInput;

报错信息(中文翻译)

类型 '{ ref?: LegacyRef<HTMLInputElement> | undefined; key?: Key | null | undefined; accept?: string | undefined; alt?: string | undefined; autoComplete?: HTMLInputAutoCompleteAttribute | undefined; ... 295 more ...; innerRef?: ((instance: any) => void) | undefined; } | { ...; } | { ...; }' 不能赋值给类型 'DetailedHTMLProps<InputHTMLAttributes<HTMLInputElement>, HTMLInputElement>'。
  类型 '{ ref?: LegacyRef<HTMLSelectElement> | undefined; key?: Key | null | undefined; autoComplete?: string | undefined; disabled?: boolean | undefined; ... 275 more ...; checked?: boolean | undefined; }' 不能赋值给类型 'DetailedHTMLProps<InputHTMLAttributes<HTMLInputElement>, HTMLInputElement>'。
    类型 '{ ref?: LegacyRef<HTMLSelectElement> | undefined; key?: Key | null | undefined; autoComplete?: string | undefined; disabled?: boolean | undefined; ... 275 more ...; checked?: boolean | undefined; }' 不能赋值给类型 'ClassAttributes<HTMLInputElement>'。
      属性'ref'的类型不兼容。
        类型 'LegacyRef<HTMLSelectElement> | undefined' 不能赋值给类型 'LegacyRef<HTMLInputElement> | undefined'。
          类型 '(instance: HTMLSelectElement | null) => void' 不能赋值给类型 'LegacyRef<HTMLInputElement> | undefined'。
            类型 '(instance: HTMLSelectElement | null) => void' 不能赋值给类型 '(instance: HTMLInputElement | null) => void'。
              参数'instance'和'instance'的类型不兼容。
                类型 'HTMLInputElement | null' 不能赋值给类型 'HTMLSelectElement | null'。
                  类型 'HTMLInputElement' 缺少类型 'HTMLSelectElement' 中的以下属性: length, options, selectedIndex, selectedOptions 及另外4个属性。ts(2322)
(property) JSX.IntrinsicElements.input: React.DetailedHTMLProps<React.InputHTMLAttributes<HTMLInputElement>, HTMLInputElement>

修复方案

核心问题是FieldHookConfig默认泛型范围覆盖所有表单元素(如select、checkbox等),导致TypeScript判定props可能属于其他表单元素,与<input>属性不兼容。只需明确限定FieldHookConfig的元素类型为HTMLInputElement:

import { FieldHookConfig, useField } from 'formik';
import React from 'react';

interface IFieldProps {
  label?: string;
}

// 明确指定FieldHookConfig的第二个泛型参数为HTMLInputElement
const MyTextInput: React.FC<IFieldProps & FieldHookConfig<string, HTMLInputElement>> = ({
  label,
  ...props
}) => {
  const { name } = props;
  const [field, meta] = useField(props);

  return (
    <div className="flex flex-col">
      <label htmlFor={name}>{label}</label>
      <input id={name} type="text" {...field} {...props} /> {/* 错误修复 */}
    </div>
  );
};

export default MyTextInput;

原理说明

FieldHookConfig的第二个泛型参数用于指定表单元素类型,默认值是HTMLElement,会涵盖所有表单相关元素。指定为HTMLInputElement后,TypeScript会将props类型限定为<input>元素的属性,既解决了ref等属性的类型冲突,又保留了自动传递所有input相关props的能力,无需逐个手动指定。


内容的提问来源于stack exchange,提问作者ThanK

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 05:50:02