React组件遇TS2339错误:Readonly<{}>类型不存在items属性
解决TS2339: Property 'items' does not exist on type 'Readonly<{}>'错误
这个错误的核心原因是你没有在React组件类的泛型声明中正确指定状态的类型,导致TypeScript无法识别this.state上的items属性。
问题分析
你已经定义了IAbstractFactoryState接口来描述状态结构,但在组件类声明时,状态泛型参数用的是空对象{}:
export default class Abstractfactory extends React.Component<IAbstractFactoryProps, {}> {
TypeScript会严格按照这个泛型参数推断this.state的类型为Readonly<{}>,自然会认为this.state.items是不存在的属性——静态类型检查是编译阶段的操作,不会考虑你后续运行时给this.state赋值的逻辑。
解决方案
1. 修正组件类的泛型参数
把状态泛型参数从{}替换成你定义的IAbstractFactoryState,这是解决问题的关键:
export default class Abstractfactory extends React.Component<IAbstractFactoryProps, IAbstractFactoryState> {
2. 优化构造函数(可选但推荐)
React组件的构造函数不需要手动接收state参数,而且初始化state的逻辑最好直接放在构造函数里,避免在外部方法中直接赋值this.state(这不符合React的最佳实践):
constructor(props: IAbstractFactoryProps) { super(props); // 先设置数据源对应的DAO this.setDaos(props.datasource); // 直接初始化state this.state = { items: this.customerDao.listCustomers(), }; }
3. 移除不规范的setInitialState方法
原代码中的setInitialState方法直接给this.state赋值的写法并不规范,建议删除这个方法,把初始化逻辑整合到构造函数中。如果后续需要重置状态,可以改用this.setState方法。
修改后的完整组件代码片段
import * as React from 'react'; import { IAbstractFactoryProps } from "./IAbstractFactoryProps"; import { IAbstractFactoryState } from "./IAbstractFactoryState"; import styles from './Abstractfactory.module.scss'; import { escape } from '@microsoft/sp-lodash-subset'; import DaoFactory from "./DaoFactory"; import ICustomerDao from "./ICustomerDao"; import DataSources from "./DatasourcesEnum"; export default class Abstractfactory extends React.Component<IAbstractFactoryProps, IAbstractFactoryState> { private customerDao: ICustomerDao; constructor(props: IAbstractFactoryProps) { super(props); this.setDaos(props.datasource); this.state = { items: this.customerDao.listCustomers(), }; } public render(): React.ReactElement<IAbstractFactoryProps> { return ( <div className={ styles.abstractfactory }> <div className={ styles.container }> <div className={ styles.row }> <div className={ styles.column }> {this.state.items.map(i => (<div>{i.id}</div>))} </div> </div> </div> </div> ); } private setDaos(datasource: string): void { const data: DataSources = datasource === "Sharepoint" ? DataSources.SharepointList : DataSources.JsonData; this.customerDao = DaoFactory.getDAOFactory(data).getCustomerDAO(); } }
额外注意点
- 如果
listCustomers是异步方法(比如从API获取数据),不要在构造函数里直接赋值,应该在componentDidMount生命周期方法中调用并通过this.setState更新状态。 - 确保
IAbstractFactoryState接口的导入路径正确,避免因导入错误导致TypeScript无法识别类型。
内容的提问来源于stack exchange,提问作者Luis Valencia
相关产品推荐
相关产品推荐

