【问题标题】:Class constructor type extending another and intersecting at the same time类构造函数类型扩展另一个并同时相交
【发布时间】:2020-07-27 10:34:51
【问题描述】:

这是来自react-router 库的 HOC 的 TS 类型:

export function withRouter<P extends RouteComponentProps<any>, C extends React.ComponentType<P>>(
    component: C & React.ComponentType<P>,
): React.ComponentClass<Omit<P, keyof RouteComponentProps<any>> & WithRouterProps<C>> & WithRouterStatics<C>;

让我感到困惑的是:C extends React.ComponentType&lt;P&gt;C &amp; React.ComponentType&lt;P&gt;。交叉口类型的目的是什么?为什么不只将component: C 作为withRouter 的参数?

【问题讨论】:

    标签: reactjs typescript react-router


    【解决方案1】:

    这是一个通过函数推断来推断CP 的类型的技巧。通常,类型参数只是推断的形式参数,而不是来自其他类型参数。所以即使我们在PC (P extends RouteComponentProps&lt;any&gt;, C extends React.ComponentType&lt;P&gt;) 之间有关系,P 也不会根据C 推断出来

    
    function X(p: RouteComponentProps<{ p: string }>){
        return null!
    }
    
    export declare function withRouter<P extends RouteComponentProps<any>, C extends React.ComponentType<P>>(
        component: C
    ): React.ComponentClass<Omit<P, keyof RouteComponentProps<any>> & WithRouterProps<C>> & WithRouterStatics<C>;
    
    
    let x2 = withRouter(X) // P is RouteComponentProps<any>
    

    Playground Link

    现在,如果参数属于交集类型,则该参数的参数将用作交集中两种类型的推理站点。因此,当我们有C &amp; React.ComponentType&lt;P&gt; 时,参数X 将用于推断React.ComponentType&lt;P&gt; 中的CP

    export declare function withRouter<P extends RouteComponentProps<any>, C extends React.ComponentType<P>>(
        component: C &  React.ComponentType<P>
    ): React.ComponentClass<Omit<P, keyof RouteComponentProps<any>> & WithRouterProps<C>> & WithRouterStatics<C>;
    
    
    let x2 = withRouter(X) // P is { p: string }
    

    Playground Link

    请注意,在 TS 的较新版本中,我们可以使用条件类型从 C 中提取 P,而无需使用交集技巧(尽管这里可能存在 2.8 之前的兼容约束,或者我可能没有的性能约束意识到)。所以我们可以将 HOC 重写为:

    export declare function withRouter<C extends React.ComponentType<RouteComponentProps<any>>>(
        component: C 
    ): React.ComponentClass<Omit<React.ComponentProps<C>, keyof RouteComponentProps<any>> & WithRouterProps<C>> & WithRouterStatics<C>;
    
    
    let x2 = withRouter(X) // P is { p: string }
    

    React.ComponentProps是react中定义的条件类型。

    Playground Link

    【讨论】:

    • 非常感谢您的详细回答,现在我明白了。阅读您的答案总是很愉快,继续努力。
    猜你喜欢
    • 2021-02-13
    • 1970-01-01
    • 1970-01-01
    • 2019-08-05
    • 2022-01-22
    • 1970-01-01
    • 2018-08-24
    • 1970-01-01
    • 2019-09-15
    相关资源
    最近更新 更多