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
相关产品推荐
相关产品推荐

