Reactjs 反应+;Typescript:在更改处理程序中动态设置值时获取类型错误

Reactjs 反应+;Typescript:在更改处理程序中动态设置值时获取类型错误,reactjs,typescript,react-component,Reactjs,Typescript,React Component,我正在尝试基于对象数组动态创建一个表单 这里的目标是在单击AddUser按钮时动态创建用户帐户,并将用户的整个状态对象提交到后端 获取此错误“元素隐式具有“any”类型,因为类型“{name:string;age:string;}”没有索引签名” 我是新的反应!我们将不胜感激 我做错了什么 import * as React from "react"; interface State{ users:User[] } interface Props{ } interface User{

我正在尝试基于对象数组动态创建一个表单

这里的目标是在单击AddUser按钮时动态创建用户帐户,并将用户的整个状态对象提交到后端

获取此错误“元素隐式具有“any”类型,因为类型“{name:string;age:string;}”没有索引签名

我是新的反应!我们将不胜感激

我做错了什么

import * as React from "react";

interface State{
  users:User[]
}
interface Props{

}
interface User{
  name:string,
  age:number;
}

class App extends React.Component<Props,State> {

   state = {
      users: [{name:"", age:""}],
   }

   handleChange = (value:number,event  : React.ChangeEvent<HTMLInputElement>) => {
    let users = [...this.state.users];
    console.log(event.target.value);
    users[value][event.target.name] = event.target.value;
    this.setState({ users }, () => console.log(this.state.users))
   }

   addUser = () => {    
    this.setState((prevState) => ({
      users: [...prevState.users, {name:"", age:""}],
    }));
   }

   handleSubmit = (e:any) => { 
       e.preventDefault();
       console.log(this.state.users) 
   }

   render() {
     let { users} = this.state
     return (
      <form onSubmit={this.handleSubmit} >
        <button onClick={this.addUser}>Add new cat</button>
        {
          users.map((val, id)=> {
            return (
              <div key={id}>
                <input
                  type="text"
                  name="name"                 
                  value={users[id].name}                   
                  onChange = {(e) =>this.handleChange(id,e)}
                />

                <input
                  type="text"
                  name="age"
                  value={users[id].age}                  
                  onChange = {(e) => this.handleChange(id,e)}
                />
              </div>
            )
          })
        }
        <input type="submit" value="Submit" /> 
      </form>
    )
  }
}
export default App;
import*as React from“React”;
界面状态{
用户:用户[]
}
界面道具{
}
界面用户{
名称:string,
年龄:人数;
}
类应用程序扩展了React.Component{
状态={
用户:[{name:,age:}],
}
handleChange=(值:number,事件:React.ChangeEvent)=>{
让用户=[…this.state.users];
日志(event.target.value);
用户[value][event.target.name]=event.target.value;
this.setState({users},()=>console.log(this.state.users))
}
addUser=()=>{
this.setState((prevState)=>({
用户:[…prevState.users,{name:,age:}],
}));
}
handleSubmit=(e:any)=>{
e、 预防默认值();
console.log(this.state.users)
}
render(){
让{users}=this.state
返回(
添加新的猫
{
users.map((val,id)=>{
返回(
this.handleChange(id,e)}
/>
this.handleChange(id,e)}
/>
)
})
}
)
}
}
导出默认应用程序;

首先,用户界面错误。将年龄强制转换为数字,并将年龄设置为空字符串“”

其次,在使用Array.prototype.map时,不使用索引[id]。you map()函数的实现看起来有点奇怪。来自MDN

map()方法使用调用 在调用数组中的每个元素上提供函数

你们可以阅读更多关于地图的信息

import*as React from“React”;
界面道具{
}
界面用户{
名称:字符串;
年龄:数字|字符串;
}
界面状态{
用户:用户[];
}
类应用程序扩展了React.Component{
建造师(道具:道具){
超级(道具);
此.state={
用户:[{姓名:,年龄:}]
};
}
handleChange=(值:number,事件:React.ChangeEvent)=>{
让用户=[…this.state.users];
用户[value][event.target.name]=event.target.value;
this.setState({users},()=>console.log(this.state.users));
};
addUser=()=>{
this.setState(prevState=>({
用户:[…prevState.users,{name:,age:}]
}));
};
handleSubmit=(e:any)=>{
e、 预防默认值();
console.log(this.state.users);
};
render(){
const{users}=this.state;
返回(
添加新的猫
{users.map((用户,id)=>{
返回(
this.handleChange(id,e)}
/>
this.handleChange(id,e)}
/>
);
})}
);
}
}
导出默认应用程序;

首先,用户界面错误。将年龄强制转换为数字,并将年龄设置为空字符串“”

其次,在使用Array.prototype.map时,不使用索引[id]。you map()函数的实现看起来有点奇怪。来自MDN

map()方法使用调用 在调用数组中的每个元素上提供函数

你们可以阅读更多关于地图的信息

import*as React from“React”;
界面道具{
}
界面用户{
名称:字符串;
年龄:数字|字符串;
}
界面状态{
用户:用户[];
}
类应用程序扩展了React.Component{
建造师(道具:道具){
超级(道具);
此.state={
用户:[{姓名:,年龄:}]
};
}
handleChange=(值:number,事件:React.ChangeEvent)=>{
让用户=[…this.state.users];
用户[value][event.target.name]=event.target.value;
this.setState({users},()=>console.log(this.state.users));
};
addUser=()=>{
this.setState(prevState=>({
用户:[…prevState.users,{name:,age:}]
}));
};
handleSubmit=(e:any)=>{
e、 预防默认值();
console.log(this.state.users);
};
render(){
const{users}=this.state;
返回(
添加新的猫
{users.map((用户,id)=>{
返回(
this.handleChange(id,e)}
/>
this.handleChange(id,e)}
/>
);
})}
);
}
}
导出默认应用程序;

事件.target.value的类型是字符串,不一定是
'name'|'age'
所以当您调用时:

users[value][event.target.name]=event.target.value

Typescript无法确定
用户[值]
将具有此索引。这就是为什么您可以更改用户界面:

interface User {
    name:string,
    age:number;
    [key: string]: string | number
}
或者,您可以检查密钥是否符合您的期望:

const keyName = event.target.name
if (keyName === 'name' || keyName === 'age') {
    users[value][keyName] = event.target.value;
}

event.target.value
的类型是字符串,而不一定是
'name'|'age'
因此在调用时:

users[value][event.target.name]=event.target.value

Typescript无法确定
用户[值]
将具有此索引。这就是为什么您可以更改用户界面:

interface User {
    name:string,
    age:number;
    [key: string]: string | number
}
或者,您可以检查密钥是否符合您的期望:

const keyName = event.target.name
if (keyName === 'name' || keyName === 'age') {
    users[value][keyName] = event.target.value;
}

完美的非常感谢,非常完美!多谢