Skip to content

Commit

Permalink
Changed HOC problem
Browse files Browse the repository at this point in the history
  • Loading branch information
mattpocock committed Aug 7, 2023
1 parent 50acd9b commit ed9bf17
Show file tree
Hide file tree
Showing 3 changed files with 110 additions and 15 deletions.
15 changes: 0 additions & 15 deletions src/08-advanced-patterns/67-hoc.problem.tsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,5 @@
import { Router, useRouter } from "fake-external-lib";

/**
* A higher-order component is a function that takes a component and returns a
* new component, with some additional props/behavior.
*
* In this case, we want to take a component that doesn't have a router prop,
* and add one.
*
* 1. Figure out the correct typings for the `withRouter` function. You'll
* need to use:
*
* - Generics
* - Omit
* - React.ComponentType
* - Probably an 'as' at least once
*/
export const withRouter = (Component: any) => {
const NewComponent = (props: any) => {
const router = useRouter();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import { Router, useRouter } from "fake-external-lib";
import { Equal, Expect } from "../helpers/type-utils";

export const withRouter = <TProps extends { router: Router }>(
Component: React.FC<TProps>,
) => {
const NewComponent = (props: Omit<TProps, "router">) => {
const router = useRouter();
return <Component {...(props as TProps)} router={router} />;
};

NewComponent.displayName = `withRouter(${Component.displayName})`;

return NewComponent;
};

type TableProps<T> = {
data: T[];
renderRow: (item: T) => React.ReactNode;
router: Router;
};

export const Table = <T,>(props: TableProps<T>) => {
return <table />;
};

const WrappedTable = withRouter(Table);

<>
{/* @ts-expect-error router is required! */}
<Table
data={[1, 2, 3]}
renderRow={(row) => {
type test = Expect<Equal<typeof row, number>>;
return <tr />;
}}
/>

<WrappedTable
data={[1, 2, 3]}
renderRow={(row) => {
type test = Expect<Equal<typeof row, number>>;
return <tr />;
}}
/>

<WrappedTable
data={[1, 2, 3]}
renderRow={(row) => {
type test = Expect<Equal<typeof row, number>>;
return <tr />;
}}
/>
</>;
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import { Router, useRouter } from "fake-external-lib";
import { Equal, Expect } from "../helpers/type-utils";

export const withRouter = <TProps extends { router: Router }>(
Component: (props: TProps) => React.ReactNode,
): ((props: Omit<TProps, "router">) => React.ReactNode) => {
const NewComponent = (props: Omit<TProps, "router">) => {
const router = useRouter();
return <Component {...(props as TProps)} router={router} />;
};

NewComponent.displayName = `withRouter(${
(Component as { displayName?: string }).displayName
})`;

return NewComponent;
};

type TableProps<T> = {
data: T[];
renderRow: (item: T) => React.ReactNode;
router: Router;
};

export const Table = <T,>(props: TableProps<T>) => {
return <table />;
};

const WrappedTable = withRouter(Table);

<>
{/* @ts-expect-error router is required! */}
<Table
data={[1, 2, 3]}
renderRow={(row) => {
type test = Expect<Equal<typeof row, number>>;
return <tr />;
}}
/>

<WrappedTable
data={[1, 2, 3]}
renderRow={(row) => {
type test = Expect<Equal<typeof row, number>>;
return <tr />;
}}
/>

<WrappedTable
data={[1, 2, 3]}
renderRow={(row) => {
type test = Expect<Equal<typeof row, number>>;
return <tr />;
}}
/>
</>;

0 comments on commit ed9bf17

Please sign in to comment.