简体   繁体   English

如何在 React 高阶组件上保留泛型?

[英]How can I preserve generics on a React higher-order component?

Let's say I want to use the React higher-order component pattern to transform a subset of my props before they hit my component:假设我想使用 React高阶组件模式在我的 props 击中我的组件之前对其进行转换:

type UpstreamProps<X> = {
    foo?: number
    bar?: string
    baz:  X
}

type DownstreamProps<X> = {
    foo: number
    bar: string
    baz: X
    bix: string
}

function transform<X>(props: UpstreamProps<X>): DownstreamProps<X> {
    return {
        ...props,
        foo: props.foo || 0,
        bar: props.bar || '(unknown)',
        bix: `${props.foo}-${props.bar}-bix`
    }
}

At the widget definition, I want to use downstream (strict) props:在小部件定义中,我想使用下游(严格)道具:

function Parent<X>(props: DownstreamProps<X> & {formatter: (x: X) => string}) {
    return (
        <>
            foo = {props.foo}
            bar = {props.bar}
            baz = {props.formatter(props.baz)}
            bix = {props.bix}
        </>
    )
}

At the call site, I should be able to pass in upstream (optional) props:在呼叫站点,我应该能够传入上游(可选)道具:

<WrappedParent<number>
    baz={22}
    formatter={(x: number) => `my number squared is ${Math.pow(x, 2)}`}
/>

This is as close as I've gotten to writing the higher-order component, but I can't get it to play well with the generics on the Parent / WrappedParent :这与我编写高阶组件一样接近,但我无法让它与Parent / WrappedParent上的泛型很好地配合使用:

function withDownstreamProps<X, OtherProps>(
    WrappedComponent: React.ComponentType<DownstreamProps<X> & OtherProps>
) {
    return function({foo, bar, baz, ...otherProps}: UpstreamProps<X> & OtherProps) {
        return (
            <WrappedComponent
                {...otherProps}
                {...transform({foo, bar, baz})}
            />
        )
    }
}

export default withDownstreamProps(Parent) // doesn't keep generics

How can I write and/or use my higher-order component wrapper to preserve the generics on the WrappedParent ?如何编写和/或使用我的高阶组件包装器来保留WrappedParent上的泛型?

The generic type you want to assign to the WrappedParent should be given to the withDownstreamProps HOC not to the resulting component:您要分配给WrappedParent的泛型类型应该给withDownstreamProps HOC 而不是结果组件:

export default withDownstreamProps<number>(Parent)

Now the type of the baz property in the WrappedParent will be number .现在WrappedParentbaz属性的类型将是number

If my answer was helpful an upvote would be appreciated.如果我的回答有帮助,将不胜感激。

Would something like that work for your case?:这样的事情对你的情况有用吗?:

type Wrapped<X, Other> = React.ComponentType<Output<X> & Other>

function withDownstreamProps<C extends Wrapped<any, any>>(
    WrappedComponent: C
) {
    return function<X, OtherProps>({foo, bar, baz, ...otherProps}: Input<X> & OtherProps) {
        return (
            <WrappedComponent
                {...otherProps}
                {...transform({foo, bar, baz})}
            />
        )
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 我如何理解 React.Component 和高阶组件之间的区别? - How can I understand differences between React.Component and Higher-Order Components? React:是否可以在容器组件内调用更高阶的组件? - React: Is it possible to call a higher-order component within a container component? React:有更好的模式用于高阶组件渲染吗? - React: is there a better pattern for higher-order component rendering? 在 React 高阶组件中包含模态功能 - Include Modal functionality in React Higher-Order Component 这是 React 中高阶组件 (HOC) 的有效实现吗? - Is this an efficient implementation of a higher-order component (HOC) in React? 如何在React.js中制作通用的“过滤器”高阶组件? - How to make a generic 'filter' Higher-Order Component in React.js? 您可以在高阶组件中为 WrappedComponent 添加子组件吗? - Can you add children to WrappedComponent in a Higher-Order Component? 如何将高阶组件连接到 Redux 存储? - How to connect a Higher-Order Component to a Redux store? 我可以在React Router的交换机内部使用高阶私有路由组件吗? - Can I use higher-order private route components inside a Switch in React Router? 用高阶组件包装递归组件 - Wrap a recursive Component with a higher-order component
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM