类型'typeof FactoryMethod上不存在属性'propTypes'

时间:2017-10-24 11:46:24

标签: reactjs typescript

我有以下组件,我想验证其中一个属性,但我收到此错误

属性'propTypes'在类型'typeof FactoryMethod

上不存在

根据文件

,我看起来不错
//#region Imports
import * as React from "react";
import styles from "./FactoryMethod.module.scss";
import { IFactoryMethodProps } from "./IFactoryMethodProps";
import {
  IDetailsListItemState,
  IDetailsNewsListItemState,
  IDetailsDirectoryListItemState,
  IDetailsAnnouncementListItemState,
  IFactoryMethodState
} from "./IFactoryMethodState";
import { IListItem } from "./models/IListItem";
import { IAnnouncementListItem } from "./models/IAnnouncementListItem";
import { INewsListItem } from "./models/INewsListItem";
import { IDirectoryListItem } from "./models/IDirectoryListItem";
import { escape } from "@microsoft/sp-lodash-subset";
import { SPHttpClient, SPHttpClientResponse } from "@microsoft/sp-http";
import { ListItemFactory} from "./ListItemFactory";
import { TextField } from "office-ui-fabric-react/lib/TextField";
import {
  DetailsList,
  DetailsListLayoutMode,
  Selection,
  IColumn
} from "office-ui-fabric-react/lib/DetailsList";
import { MarqueeSelection } from "office-ui-fabric-react/lib/MarqueeSelection";
import { autobind } from "office-ui-fabric-react/lib/Utilities";
import PropTypes from "prop-types";
//#endregion


export default class FactoryMethod extends React.Component<IFactoryMethodProps, IFactoryMethodState> {
  private listItemEntityTypeName: string = undefined;
  private _selection: Selection;

  constructor(props: IFactoryMethodProps, state: any) {
    super(props);
    this.setInitialState();
    this._configureWebPart = this._configureWebPart.bind(this);
  }


  public componentWillReceiveProps(nextProps: IFactoryMethodProps): void {
    this.listItemEntityTypeName = undefined;
    this.setInitialState();
  }

  public componentDidMount(): void {
    this.readItemsAndSetStatus();
  }

  public setInitialState(): void {
    this.state = {
      type: "ListItem",
      status: this.listNotConfigured(this.props)
        ? "Please configure list in Web Part properties"
        : "Ready",
      DetailsListItemState:{
        columns:[],
        items:[]
      },
      DetailsNewsListItemState:{
        columns:[],
        items:[]
      },
      DetailsDirectoryListItemState:{
        columns:[],
        items:[]
      },
      DetailsAnnouncementListItemState:{
        columns:[],
        items:[]
      },
    };
  }

  private _configureWebPart(): void {
    this.props.configureStartCallback();
  }

  // reusable inline component
  public ListMarqueeSelection = (itemState: {columns: IColumn[], items: IListItem[] }) => (
      <div>
        <MarqueeSelection selection={ this._selection }>
          <DetailsList
            items={ itemState.items }
            columns={ itemState.columns }
            setKey="set"
            layoutMode={ DetailsListLayoutMode.fixedColumns }
            selection={ this._selection }
            selectionPreservedOnEmptyClick={ true }
            compact={ true }>
          </DetailsList>
        </MarqueeSelection>
      </div>
  )

  public render(): React.ReactElement<IFactoryMethodProps> {
      this.readItemsAndSetStatus();
      switch(this.props.listName)      {
          case "GenericList":
            // tslint:disable-next-line:max-line-length
            return <this.ListMarqueeSelection items={this.state.DetailsListItemState.items} columns={this.state.DetailsListItemState.columns} />;
          case "News":
            // tslint:disable-next-line:max-line-length
            return <this.ListMarqueeSelection items={this.state.DetailsNewsListItemState.items} columns={this.state.DetailsNewsListItemState.columns}/>;
          case "Announcements":
            // tslint:disable-next-line:max-line-length
            return <this.ListMarqueeSelection items={this.state.DetailsAnnouncementListItemState.items} columns={this.state.DetailsAnnouncementListItemState.columns}/>;
          case "Directory":
            // tslint:disable-next-line:max-line-length
            return <this.ListMarqueeSelection items={this.state.DetailsDirectoryListItemState.items} columns={this.state.DetailsDirectoryListItemState.columns}/>;
          default:
            return null;
      }
  }

  // read items using factory method pattern and sets state accordingly
  private readItemsAndSetStatus(): void {

    this.setState({
      status: "Loading all items..."
    });

    const factory: ListItemFactory = new ListItemFactory();
    const items: IListItem[] = factory.getItems(this.props.spHttpClient, this.props.siteUrl, this.props.listName);
    const keyPart: string = this.props.listName === "GenericList" ? "" : this.props.listName;
    if(items != null  )
    {
      // the explicit specification of the type argument `keyof {}` is bad and
      // it should not be required.
      this.setState<keyof {}>({
        status: `Successfully loaded ${items.length} items`,
        ["Details" + keyPart + "ListItemState"] : {
          items,
          columns: [
          ]
        }
      });
    }

  }

  private listNotConfigured(props: IFactoryMethodProps): boolean {
    return props.listName === undefined ||
      props.listName === null ||
      props.listName.length === 0;
  }
}

FactoryMethod.propTypes =  {
  listName: React.PropTypes.oneOf(["GenericList","Announcements","News"])
}

更新1:

enter image description here

更新2

IFactoryMethodProps

import { SPHttpClient } from "@microsoft/sp-http";
import IDataProvider  from "./dataproviders/IDataProvider";

export interface IFactoryMethodProps {
  listName: string;
  spHttpClient: SPHttpClient;
  siteUrl: string;
  dataProvider: IDataProvider;
  configureStartCallback: () => void;
}

2 个答案:

答案 0 :(得分:2)

我认为你应该这样做:

        ⌄
import type { IFactoryMethodProps } from "./IFactoryMethodProps";

因为它看起来像是要导入类型别名

https://flow.org/en/docs/types/modules/

答案 1 :(得分:1)

在附加propTypes之前,您似乎可能正在导出。

尝试改变这一点:

export default class FactoryMethod 

对此:

class FactoryMethod

然后,在底部做这个:

FactoryMethod.propTypes =  {
  listName: React.PropTypes.oneOf(["GenericList","Announcements","News"])
}

export default FactoryMethod;