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

TypeScript+React表单赋值报ts(7015)错误,求替代[e.target.name]的实现方案

解决方案

你要求的不使用e.target.name的实现可以通过显式传递字段名作为handleChange参数的方式完成,既能完全避开TS索引类型报错,还能提前规避字段名拼写不一致的隐性问题。

原来的代码还存在两个隐性问题需要同步修复:

  • 表单项拷贝逻辑错误:let newFormValues = [{...formValues}]是把整个数组展开为对象属性塞入新数组的第一个元素,无法正确更新对应下标的表单项
  • 字段名拼写不一致:课时对应的input的name属性写的是numberOfClasses,但类型定义里的字段名是numOfClasses,即便解决TS报错也会赋值失败

修改后的完整代码如下:

import { useState } from 'react';

type FormValueType = {
  name: string;
  numOfClasses: number;
  price: number;
}[];

function App() {
  const [formValues, setFormValues] = useState<FormValueType>([{name:"", numOfClasses: 0, price: 0}])

  const addStudioFields = () => {
    setFormValues([...formValues, {name: "", numOfClasses:0, price:0}])
  }

  // 新增field参数,类型限定为表单项的合法键
  const handleChange = (i: number, field: keyof FormValueType[number], e: React.ChangeEvent<HTMLInputElement>) => {
    // 先拷贝整个表单数组
    const newFormValues = [...formValues];
    // 再拷贝对应下标的表单项,避免修改原状态引用
    newFormValues[i] = {
      ...newFormValues[i],
      // 数字类型字段自动转数值,其余直接用字符串
      [field]: field === 'name' ? e.target.value : Number(e.target.value)
    };
    setFormValues(newFormValues)
  }


  return (
    <div className="App">
      <header className="App-header">
        <h1>Class Picker</h1>
        <h2>
          Find the best membership option
        </h2>
        <div className="studios-container">
        <form>
          {formValues.map((element, index) => (
            <div className="form-inline" key={index}>
              <label>name</label>
              {/* 直接显式传递字段名,不依赖e.target.name */}
              <input type="text" value={element.name || ""} onChange={e => handleChange(index,'name',e)}/>
              <label>period</label>
              <input type="number" value={element.numOfClasses || 0} onChange={e => handleChange(index, 'numOfClasses', e)} />
              <label>price</label>
              <input type="number" value={element.price || 0} onChange={e => handleChange(index,'price',e)}/>
            </div>
          ))}
        </form>
        <button className="button add" type="button" onClick={() => addStudioFields()}>Add</button>
        </div>
      </header>
    </div>
  );
}

核心修改说明

  • 完全移除了对e.target.name的依赖,所有字段名通过参数显式传递,TS会自动校验字段名合法性,不会出现类型报错
  • 修复了原有的状态拷贝逻辑,符合React不可变数据的更新要求
  • 新增了类型适配逻辑,保证数字类型字段不会被错误赋值为字符串,完全匹配你定义的TypeScript类型

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 04:06:03