【问题标题】:How to properly assign generic props when using HoC?使用 HoC 时如何正确分配通用道具?
【发布时间】:2020-01-17 08:35:06
【问题描述】:

所以我有一个组件,这个组件被传递给一个 HOC,它应该增强原始组件。

我为组件正在接收的道具声明了一个类型,但我仍然收到错误“TS2741”,它说:

Property 'auth' is missing in type '{}' but required in type 'AppProps'

我写了一个小例子,你可以在这里看到: https://stackblitz.com/edit/react-ts-huaq8s

所以我的猜测是,TypeScript 从withAuth 的返回函数中检查props 是否具有通过我们的类型声明的属性。这只会失败,因为我们正在检查的属性是稍后添加的(通过<WrappedComponent ... />

根据我目前的知识,我猜我必须以某种方式告诉 TypeScript,应该检查返回的 WrappedComponent 是否有 P。但我不知道该怎么做。

所以很明显,在我问这个问题之前,我在论坛里看了很多网上的文章和一些问题,但还是找不到答案。

有人可以帮帮我吗?

【问题讨论】:

  • 在您共享的示例中,App 似乎根本没有使用withAuth,但需要将auth 作为道具提供(您没有提供也没有将 App 包装在任何东西上) .我觉得我在这里缺少一些上下文
  • 抱歉,我忘了用withAuth 包裹App

标签: reactjs typescript


【解决方案1】:

我相信您只需要将 AppProps 类型传递给 withAuth,否则您声明的泛型不会被使用。

即:

const AppWithAuth = withAuth<AppProps>(App)

这是你要找的吗?

https://stackblitz.com/edit/react-ts-uxhgql?file=index.tsx

【讨论】:

  • 我认为没有必要使用 withAuth。没有它并从props 中删除: P,你会得到相同的结果。我通过在withAuth 中用props: any 替换props: P 解决了这个问题。但我不确定这是否是正确的方法。
【解决方案2】:

所以这可能有点复杂,我不能 100% 确信这确实是正确的方法,但这里就是这样。

这里的目标是在 HOC 中包装一个需要 auth 属性的常规组件,该 HOC 将提供该 auth 属性。为此,您需要将您的 withAuth 参数实际上是一个需要 auth 的组件(正如 App 所做的那样),而您的结果将是一个不需要的组件。

以下是实现这一目标的方法:

type Omit<T,U> = Pick<T, Exclude<keyof T, U>>; // This is standard since 3.5

interface AuthProps {
  auth: TAuthProviderUtils
}

function withAuth<P extends AuthProps>(WrappedComponent: ComponentType<P>) : ComponentType<Omit<P,keyof AuthProps>> {
  return (props: Omit<P,keyof AuthProps>) => (
    <AuthContext.Consumer>
      {auth => <WrappedComponent {...props} auth={auth} />}
    </AuthContext.Consumer>
  )
}

// This needs auth
function App<AppProps>({ auth: { user } }) {
  return (
    <div>Hello App</div>
  )
}

const AppWithAuth = withAuth(App); // This does not need auth

Working example

【讨论】:

  • 只是说我会在理解代码后立即将此答案标记为正确:D(我对 TypeScript 很陌生)
  • 我认为底线是withAuth 当给定一个采用参数P(其中P extends AuthProps)的组件时,它返回一个新的组件类型,除了参数在AuthProps(这是Omit 部分)
猜你喜欢
  • 2021-04-01
  • 2019-03-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-10-18
  • 2020-02-21
  • 1970-01-01
  • 2018-07-23
相关资源
最近更新 更多