获取 redux 的连接 HOC 的包装组件类型以与 React.RefObject 一起使用,而无需重新导入



我有一个简单的组件,用react-redux包装,我有一个ref到该组件与forwardRef: true,像这样:

// Button.tsx
class Button extends React.Component {
// ...
}
// ...
export default connect(mapStateToProps, null, null, { forwardRef: true })(Button);

现在我有一个父组件来呈现Button组件

// ButtonParent.tsx
import Button from './Button';
class ButtonParent extends React.Component {
buttonRef: React.RefObject<Button>;
public constructor(props) {
this.buttonRef = React.createRef()
}
render() {
return (
<>
<Button ref={this.buttonRef}/>
</>
);
}
}

请注意,这是该问题的最小简化再现,没有不必要的输入。

问题在于buttonRef的类型。将Button(Button.tsx的默认导出)分类为一个值,是正确的。它还建议我使用typeof,这是不正确的。

这个问题源于Button是redux连接的HOC,但ref的类型是实际的Button类组件。

可以通过重命名和重新导出Button组件来解决这个问题,如下所示:

// Button.tsx
class _Button extends React.Component {
// ...
}
// ...
export default connect(mapStateToProps, null, null, { forwardRef: true })(_Button);

,然后使用buttonRef: React.RefObject<_Button>.

但是我想知道是否有一种更容易/更干净的方法来做到这一点,也许redux以某种方式导出包装组件的类型,我只是不知道如何?

编辑:一个更简单的提取类型:

type WrappedComponentType<C extends { WrappedComponent: any }> = InstanceType<C['WrappedComponent']>;

我问这个问题差不多一年前,今天我遇到了一个类似的问题,最终又找到了这个线程。在过去的一年里,我对TypeScript有了更好的了解,所以我决定重新解决这个问题,并尝试解决这个问题,幸运的是我找到了一个解决方案!

您可以通过使用redux的ConnectedComponent类型来推断类型:

import React from "react";
import { ConnectedComponent } from "react-redux";
type WrappedComponentType<C> = C extends ConnectedComponent<any, infer T>
? T extends { ref?: React.LegacyRef<infer WrappedComponent> | undefined }
? WrappedComponent
: never
: never;

buttonRef:

的类型
this.buttonRef = React.createRef<WrappedComponentType<typeof Button>>();

如果你使用功能组件:

let buttonRef = useRef<WrappedComponentType<typeof Button>>(null);

最新更新