React: 类型 ‘Readonly<{}>’ 上不存在属性 ‘X’
React: Property ‘X’ does not exist on type ‘Readonly<{}>’
React.js 错误“Property does not exist on type ‘Readonly<{}>’”发生在我们尝试访问我们没有键入的类组件的属性或状态时。
要解决该错误,请使用类上的泛型React.Component
来键入类的道具或状态对象。
下面是错误如何发生的示例。
import React from 'react'; class App extends React.Component { constructor(props: any) { super(props); this.state = {value: ''}; // 👈️ uses state but we haven't typed it } handleChange = (event: any) => { this.setState({value: event.target.value}); }; render() { return ( <div> <form> {/* ⛔️ Error: Property 'value' does not exist on type 'Readonly<{}>'.ts(2339) */} <input onChange={this.handleChange} type="text" value={this.state.value} /> <button type="submit">Submit</button> </form> </div> ); } } export default App;
请注意,我们的类组件value
在其状态对象中有一个属性。
对象的情况也是如此props
——如果我们不显式地键入它,试图访问 props 对象的属性将导致错误。
使用 React.Component 泛型
要解决该错误,请使用类的泛型React.Component
as
React.Component<PropsObject, StateObject>
。
import React from 'react'; // 👇️ we set the props to empty object, and set the state to {value: string} class App extends React.Component<{}, {value: string}> { constructor(props: any) { super(props); this.state = {value: ''}; } handleChange = (event: any) => { this.setState({value: event.target.value}); }; render() { return ( <div> <form> <input onChange={this.handleChange} type="text" // ✅ Everything works now value={this.state.value} /> <button type="submit">Submit</button> </form> </div> ); } } export default App;
我们在类中键入了对象value
的属性state
,因此我们现在可以将其作为this.state.value
.
any
禁用类型检查
If you don’t know how to type the props or state objects and want to disable
type checking, use the any
type.
import React from 'react'; // 👇️ type checking disabled for props and state class App extends React.Component<any, any> { constructor(props: any) { super(props); this.state = {value: ''}; } handleChange = (event: any) => { this.setState({value: event.target.value}); }; render() { return ( <div> <form> <input onChange={this.handleChange} type="text" value={this.state.value} /> <button type="submit">Submit</button> </form> </div> ); } } export default App;
We used the any
type when typing the props
and state
objects, which
effectively turns off type checking.
this.props
and this.state
objects without getting a type checking error.# Explicitly type a props object
Here is an example of a class that also explicitly types the props object.
import React from 'react'; // 👇️ type props as {name: string}, and state as {value: string} class App extends React.Component<{name: string}, {value: string}> { constructor(props: any) { super(props); this.state = {value: ''}; } handleChange = (event: any) => { this.setState({value: event.target.value}); }; render() { return ( <div> <form> <input onChange={this.handleChange} type="text" value={this.state.value} /> <button type="submit">Submit</button> </form> <h1>{this.props.name}</h1> </div> ); } } export default App;
We explicitly typed the props object of the App
component to have a name
property of type string
. Now when you use the component, you would have to
provide the name prop, e.g. <App name="James Doe" />
.
# Additional Resources
您可以通过查看以下教程了解有关将 TypeScript 与 React 结合使用的更多信息: