Luis Valencia
Luis Valencia

Reputation: 34028

error TS2339: Property 'items' does not exist on type 'Readonly<{}>'

I have the following react component and I get this error:

error TS2339: Property 'items' does not exist on type 'Readonly<{}>'.

However the state has the items property

import Customer from "./Customer";

export interface IAbstractFactoryState {  
    items: Customer[];
  }

and the component:

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, {}> {
    //Private instance of customerDao, please note it returns ICustomerDao, an Interface,
    //not a concrete type
    private customerDao: ICustomerDao;

    constructor(props: IAbstractFactoryProps, state: IAbstractFactoryState) {
      super(props);
      this.setInitialState();

      // We set the Dao depending on the selected data source
      this.setDaos(props.datasource);

      //Then we set the list of customers and note, we dont care if they come from Sharepoint
      //Rest API or anything else.
      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>
      );
    }

    public setInitialState(): void {
      this.state = {
        items: []
      };
    }

    private setDaos(datasource: string): void {
      const data: DataSources = datasource === "Sharepoint" ? DataSources.SharepointList : DataSources.JsonData;
      this.customerDao = DaoFactory.getDAOFactory(data).getCustomerDAO();

      //Now, its transparent for us a UI developers what datasource was selected
      //this.customerDao.
    }
}

Upvotes: 1

Views: 2511

Answers (1)

Dowon Cha
Dowon Cha

Reputation: 84

The error is due to IAbstractFactoryState not being set as the state Type for AbstractFactory. The compiler thinks the state is going to be an empty object {}.

export default class AbstractFactory extends Component<IAbstractFactoryProps, IAbstractFactoryState> 

Additionally, the state should not be passed in through the constructor.

constructor(props: IAbstractFactoryProps) {

For states make sure you set all interface members to optional.

    export interface IAbstractFactoryState {  
        items?: Customer[];
    }

Upvotes: 1

Related Questions