如何处理带有Typescript的React中HOC注入的道具?

时间:2018-06-28 13:16:11

标签: reactjs typescript

我创建了一个简单的HOC,将方法translate注入组件中。

export interface IMessageProps {
  translate: (key: string) => string;
}

export const message = <P extends object>(
  Component: React.ComponentType<P & IMessageProps>
): React.SFC<P & IMessageProps> => (props: P) => {

  const translate = (key: string): string => messages[key];

  return <Component {...props} translate={translate}/>;
};

用法:

class MyComponent extends React.Component<IMessageProps, {}> {
  render() {
    return (
      <>{this.props.translate('hello.world')}</>
    );
  }
}

export default message(MyComponent);

当我想调用组件<MyComponent/>时出现问题,因为tsc抱怨属性translate没有传递给MyComponent并期望像<MyComponent translate={...}/>这样的东西。

Type '{}' is not assignable to type 'IntrinsicAttributes & IMessageProps & { children?: ReactNode; }'.
  Type '{}' is not assignable to type 'IMessageProps'.
    Property 'translate' is missing in type '{}'.

所以我的问题是:如何绕过这个假错误?我不想在translate中将IMessageProps设置为可选,因为tslint会抱怨{{1} }。

1 个答案:

答案 0 :(得分:5)

修改

Typescript 3.2破坏了下面的代码。直到3.2为止,除jsx标记外,不允许使用泛型类型参数进行扩展操作,并且在那里没有进行严格检查。 issue对此进行了更改。扩展操作没有得到更严格的检查,这可以分解代码。我们可以做的最简单的调整是在props上使用类型断言:

export const message = <P extends IMessageProps>(
    Component: React.ComponentType<P>
): React.SFC<Pick<P, Exclude<keyof P, keyof IMessageProps>>> => (props: Pick<P, Exclude<keyof P, keyof IMessageProps>>) => {

    const translate = (key: string): string => messages[key];

    return <Component {...props as P} translate={translate} />;
};

3.2之前

您可以使用IMessagePropsSCF中选择属性,并从Pick中选择{ {1}}

P