You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

高阶组件(HOC)转渲染属性组件的类型安全工具实现及类型推断问题求助

高阶组件(HOC)转渲染属性组件的类型安全工具实现及类型推断问题求助

我正在尝试写一个工具函数,把任意高阶组件(HOC)转换成渲染属性(Render Prop)组件。理想的使用效果如下:

type HOC<In, Out> = (C: React.ComponentType<Out>) => React.ComponentType<In>

type User = { id: string } // 示例模型

// @ts-expect-error 示例HOC,不用管实现细节,只是个模拟
const withUserFromId: HOC<{ userId: string }, { user?: User }> = C => C

// 转换为渲染属性组件
const WithUserFromId = convertHOCToRenderProps(withUserFromId)

// 使用示例
function App() {
  return (
    <>
      <WithUserFromId userId="1" render={({ user }) => <Text>{user?.id}</Text>} />
    </>
  )
}

目前我已经有一个半完成的实现,JavaScript逻辑符合预期,测试过一些HOC都能正常工作:

import React from 'react'

export type HOC<In, Out> = (C: React.ComponentType<Out>) => React.ComponentType<In>

export type WithRenderProps<In extends {}, Out extends {}> = React.FC<
  In & { render: (props: Out) => React.ReactNode }
>

/**
* 将高阶组件(HOC)转换为渲染属性组件。
* @param {HOC} hoc - 要转换的高阶组件
* @return {React.FC} 转换后的渲染属性组件
* @example
*
* const WithUserFromId = convertHOCToRenderProps(withUserFromId)
*
* <WithUserFromId userId="1" render={({ user }) => <Text>{user?.id}</Text>} />
*/
export const convertHOCToRenderProps = <In extends {}, Out extends {}>(
  hoc: HOC<In, Out>
): WithRenderProps<In, Out> => {
  const RenderPropContext = React.createContext<(props: Out) => React.ReactNode>(() => null)
  const useRenderProp = () => React.useContext(RenderPropContext)

  function Inner(outProps: Out) {
    const render = useRenderProp()
    return <>{render(outProps)}</>
  }

  const EnhancedInner = hoc(Inner)

  const Outer: WithRenderProps<In, Out> = (
    props: In & { render: (props: Out) => React.ReactNode }
  ) => {
    return (
      <RenderPropContext.Provider value={props.render}>
        <EnhancedInner {...props} />
      </RenderPropContext.Provider>
    )
  }

  return React.memo(Outer)
}

但是当我用@nozbe/with-observables测试时,类型推断出现了问题,示例代码如下:

const withProfile = withObservables<{ profile: Profile }, { profile: Profile }>(
  ['profile'],
  ({ profile }) => ({ profile })
)

const WithProfileFromId = convertHOCToRenderProps(withCalendarFromId)
//    ^? WithRenderProps<Omit<{}, never> & { profile: Profile; }, {}>

可以看到类型推断结果完全不符合预期,有没有大佬能给点思路解决这个问题?

备注:内容来源于stack exchange,提问作者david_adler

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.22 14:23:12