反应高阶组件在使用时期望注入道具,导致TypeScript错误

时间:2019-02-04 14:24:47

标签: javascript reactjs typescript higher-order-components

我已经制作了一个HOC,它为传递的组件提供网络调用的道具-因此,HOC可以处理网络调用负载指示器,错误消息等。

该代码按打字稿预期的方式工作并不满意。

在我的function zoomImage(scale, mousePosInCointainer, mousePosInImage) { var imgElement = document.getElementById("img"); imgElement.width = imgElement.width * scale; imgElement.height = imgElement.height * scale; /* TODO: Determine how I'm going to center the image over cursor */ } 中,我正在制作TestContainer.tsx道具,由HOC注入。

但是当我在getQuotes中使用包装的导出组件时,会抱怨我没有指定HOC注入的道具。

App.tsx

App.tsx:

Type error: Property 'getQuotes' is missing in type '{ message: string; }' but required in type 'Readonly<Pick<OwnProps & NetworkProps, "message" | "getQuotes">>'.  TS2741

    25 |
  > 26 |         <TestContainer message="lala" />
       |          ^
    27 |       </div>
    28 |     );
    29 |   }

这是我的HOC

      <div className="App">
        <TestContainer message="lala" />
      </div>

这是使用HOC的TestContainer

import * as React from "react";

interface Props {}

interface State {
  errors: Error[];
  isLoading: boolean;
}

export type FunctionMap = { [key: string]: (...args: any[]) => any };

export const withNetwork = <P extends Props>(
  PassedComponent: React.ComponentType<P>,
  calls: FunctionMap
) => {
  return class NetworkWrapper extends React.Component<
    Pick<P, Exclude<keyof P, keyof Props>>,
    State
  > {
    functionMap: FunctionMap;
    constructor(props: P) {
      super(props);

      this.functionMap = Object.keys(calls).reduce(
        (prev: FunctionMap, current: string) => ({
          ...prev,
          [current]: this.makeHandler(calls[current])
        }),
        {}
      );
    }
    state = { errors: [], isLoading: false };

    makeHandler = (func: (...orignalArgs: any) => any) => async (
      ...args: any[]
    ) => {
      try {
        this.setState({ isLoading: true });
        const result = await func(...args);
        this.setState({ isLoading: false });
        return result;
      } catch (error) {
        this.setState({ isLoading: false });
        this.setState(prev => ({ errors: [...prev.errors, error] }));
      }
    };

    handleDismissError = () => {
      this.setState((prev: State) => {
        const [first, ...errors] = prev.errors;
        return { errors };
      });
    };

    render() {
      const props = this.props as P;
      return (
        <div>
          {this.state.isLoading && <h3>LOADING</h3>}
          {this.state.errors.length > 0 && (
            <>
              <ul>
                {this.state.errors.map(error => (
                  // @ts-ignore
                  <li>{error.message}</li>
                ))}
              </ul>
              <button onClick={this.handleDismissError}>Dismiss</button>
            </>
          )}
          <div>
            <PassedComponent {...this.functionMap} {...props} />
          </div>
        </div>
      );
    }
  };
};

1 个答案:

答案 0 :(得分:0)

您的getQuotes道具已按要求定义。当您将getQuotes签名为可选时,它不会给出类型错误。

interface NetworkProps {
  getQuotes?: (n: number) => Promise<any>;
}

或者您需要将TestContainer与getQuotesmessage一起使用

<TestContainer message="....." getQuotes={.....}/>