将带有书架/通用道具的组件传递给TypeScript中的react-redux connect函数

时间:2020-05-16 14:04:41

标签: typescript react-redux

我正在尝试将React元素与具有任意/通用属性的react-redux连接,但是编译不正确。我尝试使用JSXElementConstructor(new (props: Props) => React.Component<Props, any>)而不是ComponentType,但是遇到了关于如何用不同类型实例化Props的错误。这是代码。任何帮助将不胜感激。

https://github.com/piotrwitek/react-redux-typescript-guide/issues/55看起来很相关,但这似乎是有关道具具有泛型,而不是道具本身是泛型。

代码

import React from "react";
import { connect } from "react-redux";

interface StoreState {
  someState: number;
}

// Tried `React.JSXElementConstructor<Pros>`
// and `(new (props: Props) => React.Component<Props, any>)`
// instead of `React.ComponentType<Props>`, but got a different error.
function createWrapperComponent<Props>(
  componentElement: React.ReactElement<
    Props,
    React.ComponentType<Props> & { update(props: Props): void }
  >
) {
  const props = componentElement.props;
  const UnconnectedComponent = componentElement.type;
  const ConnectedComponent = connect<StoreState, {}, Props, StoreState>(
    (state) => state
  )(UnconnectedComponent);

  return class WrapperComponent extends React.Component<any> {
    static update = UnconnectedComponent.update;
    render() {
      return <ConnectedComponent {...props} />;
    }
  };
}

游乐场链接: Provided

2 个答案:

答案 0 :(得分:2)

更新:Here's避免了最初转换为any的方法。现在,我要投放传递给ConnectedComponent的道具。调查那里的类型问题可能会发现是否存在比我提到的问题更多的潜在问题。


您正在做的不是声音。如果Props{ someState: string },则您的UnconnectedComponent会期望它的someState道具是string,但它会是number。 / p>

如果statePropsdispatchProps应该覆盖ownProps(这是您的代码正在执行的操作),则不确定您是否能够将类型转换为以您想要的方式自动工作。 TypeScript无法确定以下内容是否正确:

function a<Props>(
  b: { [K in keyof Props]: K extends keyof StoreState ? StoreState[K] : Props[K] }
): Omit<Props, keyof StoreState>
{
  return b;
}

也许您应该硬着头皮使用anyHere's介绍了如何尝试使面向来电者的类型更安全的示例。

如果您想让ownProps覆盖stateProps,则需要为mergeProps提供一个connect参数。

但是请注意,当您通过JSX创建ReactElement时,type字段的类型为any,如果您随后致电{ {1}}。

答案 1 :(得分:1)

您的Props没有引用任何定义的类型。所以我想把它留空可以吗?

function createComponent(componentElement: React.ReactElement<{}, React.ComponentType>) {
  const props = componentElement.props;
  const UnconnectedComponent = componentElement.type;
  const ConnectedComponent = connect<StoreState, {}, {}, StoreState>(state => state)(UnconnectedComponent);

  return <ConnectedComponent {...props} />
}