Skip to content

Instantly share code, notes, and snippets.

@raynirola
Created March 8, 2024 22:40
Show Gist options
  • Save raynirola/efacbd5c1757ae7131eab841d4a3c355 to your computer and use it in GitHub Desktop.
Save raynirola/efacbd5c1757ae7131eab841d4a3c355 to your computer and use it in GitHub Desktop.
import { JSXElementConstructor, ReactNode } from "react";
type NoInfer<T> = [T][T extends any ? 0 : 1];
type ContainsChildren = { children?: React.ReactNode };
function ProviderStack<
Providers extends [
ContainsChildren,
...ContainsChildren[]
]
>({
providers,
children,
}: {
providers: {
[k in keyof Providers]: [
JSXElementConstructor<Providers[k]>,
Omit<NoInfer<Providers[k]>, "children">
];
};
children: ReactNode;
}) {
let node = children;
for (const [Provider, props] of providers) {
node = <Provider {...props}>{node}</Provider>;
}
return node;
}
declare function ThemeProvider(props: {
theme: "dark" | "light";
children: React.ReactNode;
}): JSX.Element;
declare function UserProvider(props: {
userId: number;
children: React.ReactNode;
}): JSX.Element;
<ProviderStack
providers={[
[ ThemeProvider, { theme: "dark" } ],
[ UserProvider, { userId: 123 } ],
]}
>
<OtherComponent/>
</ProviderStack>;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment