javascript - TypeScript 不知道组件从 HOC 获取了 required prop

标签 javascript reactjs typescript high-order-component

我正在用 HOC 包装我的组件的导出,这会向它添加 prop,但是 TypeScript 看不到 HOC 已经添加了这个 prop(这是必需的)。

组件:

import * as React from "react";
import { withText } from "../hoc";

interface Props {
  text: string;
}

function TestComponent({ text }: Props) {
  return <div>{text}</div>;
}

export default withText(TestComponent);

高级组织:

import * as React from "react";
import { useContext, ReactElement, ComponentType } from "react";
import { TextContext } from "../contexts";

const withText = <P extends object>(
  Component: ComponentType<P>
): ((props: P) => ReactElement) => props => (
  <Component text={useContext(TextContext).value} {...props} />
);

export default withText;

上下文:

import { createContext } from "react";

const TextContext = createContext<{ value: string }>({
  value: ""
});

export default TextContext;

应用:

import * as React from "react";
import { render } from "react-dom";
import { TextContext } from "./contexts";
import { TestComponent } from "./components";

function App() {
  return (
    <TextContext.Provider value={{ value: "Lorem ipsum" }}>
      <TestComponent /> /* TS throws an error here */
    </TextContext.Provider>
  );
}

const rootElement = document.getElementById("root");
render(<App />, rootElement);

抛出 TS 的错误: 属性“text”在“{}”类型中缺失,但在“Props”类型中是必需的

预期行为:TypeScript 知道 'text' prop 已经被 withText HOC 添加了

链接到 codesandbox -> here

最佳答案

这应该适合你

 type Omit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>;
 interface InterfaceToOmit {
   text: string;
 }

    const withText = <P extends InterfaceToOmit>(Component: React.ComponentType<P>): React.ComponentClass<Omit<P, keyof InterfaceToOmit>> => {
      // tslint:disable-next-line:max-classes-per-file
      class MyHocClass extends React.Component<Omit<P, keyof InterfaceToOmit>> {
        public render() {
          return <Component text={'what ever your HOC component waht to pass here'} {...this.props as P} />;
        }
      }

      return MyHocClass;
    };

export default withText

您需要返回另一个组件,该组件将省略 props。因此,当您使用 withText 时,它将是仅包含这些 Prop 的组件,您不想在 HOC 组件中传递这些内容。在这个例子中它的 InterfaceToOmit

所以你的组件仍然会拥有所有的 Prop

type propsToMyComponent = {
  anything: string;
} & InterfaceToOmit;

const testComponent = (props: propsToMyComponent) => {
  return <div>asd</div>;
};

然后像这样使用它

 const WithTextComponent = withText<propsToMyComponent>(testComponent);

现在你只能用一个 prop 调用它

<WithTextComponent anything={''} />; // no error

关于javascript - TypeScript 不知道组件从 HOC 获取了 required prop,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57091125/

相关文章:

javascript - jQuery 选择器中的行为不一致

javascript - Protractor - 在 ng-repeat 中获取子元素的文本

node.js - 在 electron + react 应用程序中执行 child_process

node.js - 将 React 应用程序部署到 github 页面。获取...net::ERR_ABORTED

typescript - 在页面之间导航时如何使菜单正确显示

javascript - $scope.$watch 没有在指令中被触发

javascript - 如何在 jQuery 包装器中定位具有字符串内容的变量?

javascript - 在 React 中使用条件渲染时如何进行过渡

angular - Ionic 3 - IE11 中 ES6 的 Polyfill 不工作

node.js - 如何为模块使用外部 .d.ts