【问题标题】:Property 'propTypes' does not exist on type 'typeof FactoryMethod类型“typeof FactoryMethod”上不存在属性“propTypes”
【发布时间】:2017-10-24 11:46:23
【问题描述】:

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

类型“typeof FactoryMethod”上不存在属性“propTypes”

根据文档,我觉得没问题

//#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:

更新 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;
}

【问题讨论】:

    标签: reactjs typescript


    【解决方案1】:

    我认为你应该这样做:

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

    因为看起来您正在导入一个类型别名

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

    【讨论】:

    • 如果要导入类型别名,请在导入前添加 type 关键字(我做了一个小箭头)
    • 还有@LuisValencia:你可以用static defaultProps代替propTypesflow.org/en/docs/react/components
    • @David defaultPropspropTypes 不同
    • @DavinTryon 是的,但使用defaultProps 可以更轻松地使用流类型而不是propTypes,请参阅flow.org/en/docs/react/components
    【解决方案2】:

    看起来您可能在附加 propTypes 之前正在导出。

    尝试改变这一点:

    export default class FactoryMethod 
    

    到这里:

    class FactoryMethod
    

    然后,在底部执行以下操作:

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

    【讨论】:

    • 我试过我仍然得到同样的错误:属性'propTypes'不存在类型'typeof FactoryMethod
    • IFactoryMethodPropspropTypes 的类型定义吗?
    • 请参阅带有该接口代码的更新 2,如果问题太菜鸟,请见谅。 (教程中可能有一些不清楚的地方)
    猜你喜欢
    • 2021-01-09
    • 2020-11-10
    • 2018-08-02
    • 1970-01-01
    • 2020-10-04
    • 2020-08-19
    • 2017-11-06
    • 2018-11-09
    • 2018-04-26
    相关资源
    最近更新 更多