首页 > 解决方案 > 在 React 中组合上下文提供程序时从提供程序组件推断 prop 类型

问题描述

我正在尝试使用一个技巧(类似于example1example2)来处理 React Provider 地狱,所以而不是这个

<ThemeProvider theme={defaultTheme}>
  <FeatureFlags flags={myFlags}>
    <AuthProvider>
      <RouterProvider>
        <HttpClientProvider baseUrl="https://...">
          <UnitProvider>
            <CustomerProvider>
              <HistoryProvider>
                <App />
              </HistoryProvider>
            </CustomerProvider>
          </UnitProvider>
        </HttpClientProvider>
      </RouterProvider>
    </AuthProvider>
  </FeatureFlags>
</ThemeProvider>

可以这样做:

    <Provide
      providers={[
        [ThemeProvider, { theme: defaultTheme }],
        [FeatureFlags , { flags: myFlags }],
        AuthProvider,
        RouterProvider,
        [HttpClientProvider, {baseUrl: 'https://...'}],
        UnitProvider,
        CustomerProvider,
        HistoryProvider,
      ]}
    >
      <App />
    </Provide>

Provide组件非常简单,看起来像这样

export function Provide<T extends React.ComponentType>({
  children,
  providers,
}: {
  children: React.ReactNode;
  providers: (
    | React.ComponentType
    | [T, Omit<React.ComponentProps<T>, 'children'>]
  )[];
}) {
  return (
    <>
      {providers.reduceRight((componentTree, cfg) => {
        const [Provider, props] = Array.isArray(cfg) ? cfg : [cfg, {}];
        return <Provider {...props}>{componentTree}</Provider>;
      }, children)}
    </>
  );
}

我想在 TS 中实现一些打字帮助(例如,当我打错字时[FeatureFlags, { flagggsss: myFlags }]),但它仅从第一个提供者(ThemeProvider)推断正确类型,并使用它来检查其他提供者的类型(例如,FeatureFlags提供者失败,因为ThemeProvider没有' t有财产flags)。

我试图用inferTypeScript 的一些魔法来解决这个问题,但没有成功。是否可以以providersTS 可以正确推断每个提供者的道具类型的方式提供类型?

边注:

我知道我可以用另一种方式达到同样的效果,比如

      providers={[
        ({children}) => <ThemeProvider theme={defaultTheme}>{children}</FeatureFlags>
        ({children}) => <FeatureFlags flags={myFlags}>{children}</FeatureFlags>,
        AuthProvider,
        RouterProvider,
        ...
      ]}

但如果类型脚本可以推断提供者的原型,我更感兴趣。

标签: reactjstypescripttype-inference

解决方案


推荐阅读