在类型 '{ order_graph_1: any; 上找不到参数类型为 'string' 的索引签名order_graph_2:任意; }'

No index signature with a parameter of type 'string' was found on type '{ order_graph_1: any; order_graph_2: any; }'

interface MyProps {
    order_graph_1: any;
    order_graph_2: any;setOrder: any}

class Setup extends React.Component<MyProps, MyState>{
    orders: { order_graph_1: any; order_graph_2: any; };
    constructor(props: MyProps){
        super(props);
        this.orders = {
            "order_graph_1":this.props.order_graph_1,
            "order_graph_2":this.props.order_graph_2
        }; 
    }
    
    setOrders(event: { target: { name: React.ReactText; value: string; }; }){
        this.orders[event.target.name] = parseInt(event.target.value);
    }

我正在尝试将 JS 代码更改为 TS,但出现此错误:

this.orders[event.target.name]
Element implicitly has an 'any' type because expression of type 'ReactText' can't be used to index type '{ order_graph_1: any; order_graph_2: any; }'.
  No index signature with a parameter of type 'string' was found on type '{ order_graph_1: any; order_graph_2: any; }'.

我该如何解决这个问题?

Typescript 不知道 event.target.name 中的 stringthis.orders 的有效键。您需要断言 name 与您可接受的值匹配 as.

这是一个很常见的问题,我打算将您重定向到另一个答案,但我想解决此代码中的其他一些危险信号。

您正在将有状态数据存储在状态之外。不要这样做!您的组件不会在正确的时间以正确的值重新呈现。 orders 应该是 this.state 的一部分,无论是在此处还是在父级中。我不确定为什么在此处更新 props 时传递它们的值,这让我想知道这个组件是否应该没有状态并且应该只使用回调来设置父级的状态。 React 建议您不要基于 props here and here 创建状态。但我暂时忽略它并假设这些是初始值。

放弃 any。当您使用 any 作为类型时,您将失去打字稿的好处。 setOrders 中的值来自 parseInt,因此我们知道 order_graph_1order_graph_2 应该是类型 number。为什么不说呢?

代码:

import React from "react";

interface Orders {
  order_graph_1: number;
  order_graph_2: number;
}

interface MyProps extends Orders {
  setOrder: (...args: any) => void; // function which takes args...??
}

interface MyState extends Orders {
  otherProperty: string;
}

class Setup extends React.Component<MyProps, MyState> {
  // don't need a constructor just to set state
  state = {
    // it is best not to derive state from props
    order_graph_1: this.props.order_graph_1,
    order_graph_2: this.props.order_graph_2,
    // just to show that we can have other properties alongside the orders
    otherProperty: ""
  };

  // needs to be an arrow function to access `this` properly
  // could use ( event: React.ChangeEvent<HTMLInputElement>)
  // could avoid the assertion by passing the name as an argument
  setOrders = (event: { target: { name: React.ReactText; value: string } }) => {
    // I don't love this solution, but we can avoid the TS errors by copying the previous state
    this.setState((prevState) => ({
      ...prevState,
      [event.target.name]: parseInt(event.target.value)
    }));
  };

  // helper function avoids having to duplicate info for the two inputs
  // can set any of these atrributes: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/number
  // or https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#attributes
  renderInput = (name: keyof Orders) => (
    <>
      <label htmlFor={name}>{name}</label>
      <input
        id={name} // label htmlFor matches id
        name={name}
        value={this.state[name]}
        onChange={this.setOrders}
        type="number"
        min={0} // don't allow negatives
        step={1} // allow whole numbers only
      />
    </>
  );

  render() {
    return (
      <div>
        {this.renderInput("order_graph_1")}
        {this.renderInput("order_graph_2")}
      </div>
    );
  }
}