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

React Hook Form监听字段数组单个字段触发TypeScript错误

React Hook Form监听字段数组单个字段的TypeScript错误解决方法

问题场景

在React Hook Form中使用包含selected复选框字段的incomes字段数组,希望单独监听每个数组项的selected字段,但直接使用动态路径incomes[${index}].selected作为useWatch的name参数时,触发TypeScript错误:

No overload matches this call.

现有代码示例

Period组件(初始版本,监听整个数组)

const Period = ({ item, index, datepicker }) => {
    const { control } = useFormContext<InntektFormValues>();
    const value = useWatch({
        control,
        name: "incomes",
    });

    return value[index].selected ? datepicker : <div className="min-w-[160px]"></div>;
};

IncomeTable组件(渲染字段数组)

export const IncomeTable = () => {
    const { control } = useFormContext<IncomeFormValues>();
    const incomeField = useFieldArray({
        control,
        name: "incomes",
    });

    return (
        <>
            {incomeField.fields.map((item, index) => (
                <TableRowWrapper
                    key={item.id}
                    cells={[
                        <Period
                            item={item}
                            index={index}
                            datepicker={
                                <FormControlledDatePicker
                                    key={`incomes[${index}].from`}
                                    name={`incomes[${index}].from`}
                                    label="From"
                                    placeholder="DD.MM.ÅÅÅÅ"
                                    defaultValue={item?.from ?? null}
                                    hideLabel
                                />
                            }
                        />,
                    ]}
                />
            ))}
        </>
    );
};

尝试修改后的Period组件(触发TS错误)

const Period = ({ item, index, datepicker }) => {
    const { control } = useFormContext<InntektFormValues>();
    const value = useWatch({
        control,
        name: `incomes[${index}].selected`, // 此处触发TypeScript错误
    });
};

错误原因

TypeScript对React Hook Form的字段路径进行严格的类型校验,动态拼接的字符串路径incomes[${index}].selected无法被TS静态推断为符合InntektFormValues结构的合法字段路径(FieldPath<InntektFormValues>类型),因此抛出类型不匹配的错误。

解决方法

方法1:使用FieldPath类型断言

通过类型断言明确告诉TS,动态生成的路径是合法的字段路径:

import { FieldPath, useWatch } from 'react-hook-form';

const Period = ({ item, index, datepicker }) => {
    const { control } = useFormContext<InntektFormValues>();
    const selected = useWatch({
        control,
        name: `incomes[${index}].selected` as FieldPath<InntektFormValues>,
    });

    return selected ? datepicker : <div className="min-w-[160px]"></div>;
};

方法2:使用useController替代useWatch

useController对动态字段路径的类型支持更友好,同时能直接获取字段的value:

import { useController } from 'react-hook-form';

const Period = ({ item, index, datepicker }) => {
    const { control } = useFormContext<InntektFormValues>();
    const { field } = useController({
        control,
        name: `incomes[${index}].selected` as FieldPath<InntektFormValues>,
    });

    return field.value ? datepicker : <div className="min-w-[160px]"></div>;
};

补充说明

如果你的InntektFormValues类型定义正确,确保incomes是数组类型且每个项包含selected字段,上述方法即可解决类型错误。类型断言是安全的,因为你明确知道动态路径符合表单结构。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 22:07:39