首页 > 解决方案 > React 类组件属性中的 TypeScript 错误在类型“Readonly<{}>”上不存在,不确定如何设置状态类型

问题描述

我有一个具有两个状态属性的 React 类组件。我目前在尝试动态 setState 时遇到 TypeScript 错误Property 'input' does not exist on type 'Readonly<{}>'

我是 TypeScript 的新手,之前还没有解决将类型定义添加到类组件的问题。我一直在使用功能组件和钩子,所以这个问题还没有出现在我身上。

我为我的 App State 定义了类型,然后将其传递给组件,但我仍然收到原始错误以及我定义状态的新错误'AppState' only refers to a type, but is being used as a value here.

我一直在寻找解决方案,但无法解决这个问题。

My original component

type AppState = {
  input: string;
  imageUrl: string;
}

class App extends Component<AppState> {
  constructor(props: any) {
    super(props);
    // Error: 'AppState' only refers to a type, but is being used as a value here.
    this.state: AppState = {
      input: "",
      imageUrl: "",
    };
  }

  onInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    this.setState({ input: e.target.value });
  };

  onButtonSubmit = () => {
    // Error: Property 'input' does not exist on type 'Readonly<{}>'.
    this.setState({ imageUrl: this.state.input });
    clarifaiApp.models
      .predict(
        Clarifai.COLOR_MODEL,
        // URL
        "https://samples.clarifai.com/metro-north.jpg"
      )
      .then(
        function (response: any) {
          console.log("This is your response: ", response);
        },
        function (err: Error) {
          console.log("There was an error: ", err);
        }
      );
  };

  render() {
    return (
      <Container>
        <ImageLinkForm
          onInputChange={this.onInputChange}
          onButtonSubmit={this.onButtonSubmit}
        />
        {/* Error: Property 'imageUrl' does not exist on type 'Readonly<{}>'. */}
        <FaceRecognition imageUrl={this.state.imageUrl} />
      </Container>
    );
  }
}

export default App;

标签: javascriptreactjstypescript

解决方案


如果要初始化constructor类组件内部的状态,则必须为React.Component泛型提供两种类型的参数。第一个参数旨在提供有关道具的类型信息,第二个参数旨在提供有关state. 例如,

interface AppProps {
  // props 
}

type AppState = {
  input: string;
  imageUrl: string;
}

class App extends Component<AppProps,AppState> {
  // you don't need any more explicit type annotation here
  constructor(props) {
    super(props);
    this.state = {
      input: "",
      imageUrl: "",
    };
  }

  // rest of the app logic
}

如果您在构造函数外部的 state 字段中初始化了状态,这不会导致任何问题。

type AppState = {
  input: string;
  imageUrl: string;
}

class App extends Component {
  state: AppState = {
    input: "",
    imageUrl: ""
  }


  // rest of the app logic
}

在第二种情况下,如果组件需要一些道具,您可以选择为道具提供类型参数。例如,

interface AppProps {
  // type info for props
}

type AppState = {
  input: string;
  imageUrl: string;
}

class App extends Component<AppProps> {
   state: AppState = {
      input: "",
      imageUrl: ""
   }

   // rest of the app logic
}

推荐阅读