Typescript 无状态 HOC react-redux 注入道具打字

Posted

技术标签:

【中文标题】Typescript 无状态 HOC react-redux 注入道具打字【英文标题】:Typescript stateless HOC react-redux injected props typing 【发布时间】:2020-09-21 12:06:36 【问题描述】:

我正在使用 typescript,但我似乎无法弄清楚如何正确键入我的无状态组件,这些组件都有一个 redux HOC,可以向它们注入一些 props 和函数。

这是我的wrapper.tsx

export type Props = ReturnType<typeof mapStateToProps> &
  ReturnType<typeof mapDispatchToProps> & 
    fetchMorePosts: () => void;
  ;

const withPostFeedWrapper = <WrapperProps extends Props>(
  WrappedComponent: React.FunctionComponent<WrapperProps>
) => 
  const PostFeed: React.FunctionComponent<Props> = (props) => 
    const  postFeed, fetchPostFeed  = props;

    useEffect(() => 
      fetchPostFeed(
        offset: postFeed.offset,
        limit: postFeed.limit,
      );
    , [fetchPostFeed])

    const fetchMorePosts = useCallback(() => 
      ...do stuff
    , []);

    return (
      <WrappedComponent
        ...props as WrapperProps
        fetchMorePosts=fetchMorePosts
      />
    );
  ;

  return connect<
    ReturnType<typeof mapStateToProps>,
    ReturnType<typeof mapDispatchToProps>,
    Props,
    State
  >(
    mapStateToProps,
    mapDispatchToProps
  )(PostFeed);
;

const mapStateToProps = (state: State) => (
  postFeed: state.postFeed,
);

const mapDispatchToProps = (dispatch: ThunkDispatch<, , AnyAction>) => 
  return 
    fetchPostFeed: (variables: FetchPostFeedPostsVariables) =>
      dispatch(fetchPostFeed(variables)),
    dispatch,
  ;
;

export default withPostFeedWrapper;

这是我的子组件

import withPostFeedWrapper,  Props  from "./wrapper";

const PostFeed: React.FunctionComponent<Props> = (
  postFeed,
  fetchMorePosts,
) => 
  return (
    <>
      ...stuff
    </>
  );
;

export default withPostFeedWrapper(PostFeed)

当我这样导入它时,它会出错

import PostFeed from "containers/_post-feed";

const Homepage: React.FunctionComponent<HomepageProps> = (
  ...props
) => 

  return (
    <div className="homepage">
      <PostFeed />
    </div>
  );
;

这是错误

import PostFeed
Property 'fetchMorePosts' is missing in type '' but required in type 'Pick<Props, "fetchMorePosts">'.ts(2741)
wrapper.tsx(21, 5): 'fetchMorePosts' is declared here.

组件应该工作的方式,我在另一个文件中导入它时不需要传入props。 HOC 应该注意这一点。这段代码运行正常,只是打字稿出错了。

我错过了什么?

【问题讨论】:

【参考方案1】:

由于您的包装组件不需要传递fetchMorePosts,因此您应该将其键入为React.FunctionComponent&lt;Omit&lt;Props, 'fetchMorePosts'&gt;&gt;(该组件需要与Props 中的props 相同,只是没有'fetchMorePosts'

您也可以从connect 中省略显式类型参数,推断将正常工作(并且您传入的类型参数错误,TOwnProps 类型参数被添加到生成组件的所需道具中)

const withPostFeedWrapper = <WrapperProps extends Props>(
  WrappedComponent: React.FunctionComponent<WrapperProps>
) => 
  const PostFeed: React.FunctionComponent<Omit<Props, 'fetchMorePosts'>> = (props) => 
    const  postFeed, fetchPostFeed  = props;

    useEffect(() => 
      fetchPostFeed(
        offset: postFeed.offset,
        limit: postFeed.limit,
      );
    , [fetchPostFeed])

    const fetchMorePosts = useCallback(() => 

    , []);

    return (
      <WrappedComponent
        ...props as WrapperProps
        fetchMorePosts=fetchMorePosts
      />
    );
  ;

  return connect(
    mapStateToProps,
    mapDispatchToProps
  )(PostFeed);
;

Playground Link

【讨论】:

修复了,谢谢!关于推断 connect 中的类型的要点

以上是关于Typescript 无状态 HOC react-redux 注入道具打字的主要内容,如果未能解决你的问题,请参考以下文章

如何将道具从调用组件传递给 HOC - React + Typescript

typescript 反应HOC的ts类型声明

如何在 TypeScript 中为 React Apollo Query 组件编写 HOC?

TypeScript React HOC 返回类型与装饰器兼容

带有 React.createContext 的 Typescript HOC

React TypeScript HoC - 将组件作为道具传递