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

JSX属性禁用Lambda及TypeScript隐式any报错的解决方案咨询

解决JSX Lambda禁止和隐式Any类型的问题

我来帮你一步步搞定这两个问题,完全满足你不能修改Lambda规则的要求:

第一步:修复隐式Any类型报错

TypeScript抛出'values' implicitly has an 'any' type错误,是因为你没给values和arrayHelpers定义明确的类型。我们先从定义数据结构类型入手:

首先,明确单个设施和表单整体的类型:

// 单个设施的类型定义
type Amenity = {
  id: string;
  name: string;
};

// 整个表单的values类型
type FormValues = {
  amenitieslist: Amenity[];
  // 如果有其他表单字段,也可以在这里补充定义
};

然后给你的displayAmenities函数指定参数类型(结合react-hook-form的类型):

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

const displayAmenities = (
  values: FormValues,
  arrayHelpers: Pick<FieldArrayRenderProps, 'push' | 'remove'>
) => {
  // 你的渲染逻辑将在这里实现
};

这样TypeScript就能正确推断类型,不会再报隐式any的错误了。

第二步:替换JSX中的Lambda表达式

既然不能在JSX属性里直接写Lambda,我们可以把点击事件逻辑提取成组件内部的绑定方法,或者利用dataset传递索引,彻底避开Lambda:

方案1:组件内部绑定方法(简单直接)

假设你用的是函数组件,我们可以这样重构代码:

import { useForm, FieldArray, Field } from 'react-hook-form';

type Amenity = {
  id: string;
  name: string;
};

type FormValues = {
  amenitieslist: Amenity[];
};

const YourFormComponent = () => {
  const { control, getValues } = useForm<FormValues>({
    defaultValues: {
      amenitieslist: []
    }
  });

  // 提取添加设施的方法
  const handleAddAmenity = () => {
    const arrayHelpers = control.getFieldArray('amenitieslist');
    arrayHelpers.push({ id: "", name: "" });
  };

  // 提取移除设施的方法,通过dataset获取索引
  const handleRemoveAmenity = (e: React.MouseEvent<HTMLButtonElement>) => {
    const index = parseInt(e.currentTarget.dataset.index || '0', 10);
    const arrayHelpers = control.getFieldArray('amenitieslist');
    arrayHelpers.remove(index);
  };

  // 渲染设施列表的逻辑
  const renderAmenities = () => {
    const values = getValues();
    if (!values.amenitieslist || values.amenitieslist.length === 0) {
      return (
        <button type="button" onClick={handleAddAmenity}>
          Add an amenity
        </button>
      );
    }

    return values.amenitieslist.map((_, index) => (
      <div key={index}>
        <Field name={`amenitieslist.${index}.name`} />
        <button 
          type="button" 
          onClick={handleRemoveAmenity}
          data-index={index} // 把索引存在按钮的dataset属性中
        >
          -
        </button>
      </div>
    ));
  };

  return (
    <form>
      <FieldArray 
        name="amenitieslist"
        render={() => <div>{renderAmenities()}</div>}
      />
      <div>
        <button type="submit">Submit</button>
      </div>
    </form>
  );
};

方案2:抽分子组件+提前绑定方法(更优雅)

如果列表项逻辑复杂,你可以把单个设施项抽成子组件,并用useMemo提前绑定好每个索引的移除方法,彻底避免Lambda:

// 子组件:单个设施项
type AmenityItemProps = {
  index: number;
  onRemove: () => void;
};

const AmenityItem = ({ index, onRemove }: AmenityItemProps) => {
  return (
    <div>
      <Field name={`amenitieslist.${index}.name`} />
      <button type="button" onClick={onRemove}>
        -
      </button>
    </div>
  );
};

// 父组件
const YourFormComponent = () => {
  const { control, getValues } = useForm<FormValues>({
    defaultValues: {
      amenitieslist: []
    }
  });

  const values = getValues();
  const arrayHelpers = control.getFieldArray('amenitieslist');

  // 用useMemo提前生成绑定好索引的移除方法数组,避免每次渲染创建新函数
  const removeMethods = React.useMemo(() => {
    return values.amenitieslist.map((_, idx) => () => arrayHelpers.remove(idx));
  }, [values.amenitieslist, arrayHelpers]);

  const handleAddAmenity = () => {
    arrayHelpers.push({ id: "", name: "" });
  };

  const renderAmenities = () => {
    if (!values.amenitieslist || values.amenitieslist.length === 0) {
      return (
        <button type="button" onClick={handleAddAmenity}>
          Add an amenity
        </button>
      );
    }

    return values.amenitieslist.map((_, index) => (
      <AmenityItem 
        key={index} 
        index={index} 
        onRemove={removeMethods[index]} // 直接用提前绑定好的方法,无Lambda
      />
    ));
  };

  return (
    <form>
      <FieldArray 
        name="amenitieslist"
        render={() => <div>{renderAmenities()}</div>}
      />
      <div>
        <button type="submit">Submit</button>
      </div>
    </form>
  );
};

这两种方案都能完全避开JSX属性中的Lambda,同时解决了TypeScript的类型报错问题,完全符合你的要求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 07:31:40