Help with creating a builder pattern for main renderer
Wasn't sure how to fully articulate this but I want to have a class that lets me "build" the nested component structure that eventually gets passed into the
I think I have it working with runtime behavior, but the type definitions aren't quite right and was hoping I could get some feedback on it.
Implementation
Usage
renderrender function.I think I have it working with runtime behavior, but the type definitions aren't quite right and was hoping I could get some feedback on it.
Implementation
export class HOCBuilder {
private component: Component<Record<string, unknown>> = () => <></>;
private props?: ComponentProps<typeof this.component>;
with<T extends Component<ParentProps>>(
Wrapper: T,
wrapperProps?: ComponentProps<T>
): this {
const PreviousComponent = this.component;
const previousProps = this.props;
this.props = wrapperProps;
this.component = () => (
<Wrapper {...wrapperProps}>
<PreviousComponent {...previousProps} />
</Wrapper>
);
return this;
}
build(): Component {
return this.component;
}
}export class HOCBuilder {
private component: Component<Record<string, unknown>> = () => <></>;
private props?: ComponentProps<typeof this.component>;
with<T extends Component<ParentProps>>(
Wrapper: T,
wrapperProps?: ComponentProps<T>
): this {
const PreviousComponent = this.component;
const previousProps = this.props;
this.props = wrapperProps;
this.component = () => (
<Wrapper {...wrapperProps}>
<PreviousComponent {...previousProps} />
</Wrapper>
);
return this;
}
build(): Component {
return this.component;
}
}Usage
import { HOCBuilder, KeyboardShortcutManagerProvider } from "~/utilities";
import { type JSX } from "solid-js";
import { render } from "solid-js/web";
import App from "./App";
import { Router } from "./router";
function Foo(props: { bar: string }): JSX.Element {
return <>{props.bar}</>;
}
const Main = new HOCBuilder()
.with(Router, { root: App })
// This is giving an error! :'(
.with(Foo, { bar: "asdf" })
.with(KeyboardShortcutManagerProvider)
.build();
render(() => <Main />, document.getElementById("root")!);import { HOCBuilder, KeyboardShortcutManagerProvider } from "~/utilities";
import { type JSX } from "solid-js";
import { render } from "solid-js/web";
import App from "./App";
import { Router } from "./router";
function Foo(props: { bar: string }): JSX.Element {
return <>{props.bar}</>;
}
const Main = new HOCBuilder()
.with(Router, { root: App })
// This is giving an error! :'(
.with(Foo, { bar: "asdf" })
.with(KeyboardShortcutManagerProvider)
.build();
render(() => <Main />, document.getElementById("root")!);Argument of type '(props: { bar: string; }) => Element' is not assignable to parameter of type 'Component<{ children?: Element; }>'.
Types of parameters 'props' and 'props' are incompatible.
Property 'bar' is missing in type '{ children?: Element; }' but required in type '{ bar: string; }'.Argument of type '(props: { bar: string; }) => Element' is not assignable to parameter of type 'Component<{ children?: Element; }>'.
Types of parameters 'props' and 'props' are incompatible.
Property 'bar' is missing in type '{ children?: Element; }' but required in type '{ bar: string; }'.