Skip to content

Commit ed9bf17

Browse files
committed
Changed HOC problem
1 parent 50acd9b commit ed9bf17

File tree

3 files changed

+110
-15
lines changed

3 files changed

+110
-15
lines changed

src/08-advanced-patterns/67-hoc.problem.tsx

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,5 @@
11
import { Router, useRouter } from "fake-external-lib";
22

3-
/**
4-
* A higher-order component is a function that takes a component and returns a
5-
* new component, with some additional props/behavior.
6-
*
7-
* In this case, we want to take a component that doesn't have a router prop,
8-
* and add one.
9-
*
10-
* 1. Figure out the correct typings for the `withRouter` function. You'll
11-
* need to use:
12-
*
13-
* - Generics
14-
* - Omit
15-
* - React.ComponentType
16-
* - Probably an 'as' at least once
17-
*/
183
export const withRouter = (Component: any) => {
194
const NewComponent = (props: any) => {
205
const router = useRouter();
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
import { Router, useRouter } from "fake-external-lib";
2+
import { Equal, Expect } from "../helpers/type-utils";
3+
4+
export const withRouter = <TProps extends { router: Router }>(
5+
Component: React.FC<TProps>,
6+
) => {
7+
const NewComponent = (props: Omit<TProps, "router">) => {
8+
const router = useRouter();
9+
return <Component {...(props as TProps)} router={router} />;
10+
};
11+
12+
NewComponent.displayName = `withRouter(${Component.displayName})`;
13+
14+
return NewComponent;
15+
};
16+
17+
type TableProps<T> = {
18+
data: T[];
19+
renderRow: (item: T) => React.ReactNode;
20+
router: Router;
21+
};
22+
23+
export const Table = <T,>(props: TableProps<T>) => {
24+
return <table />;
25+
};
26+
27+
const WrappedTable = withRouter(Table);
28+
29+
<>
30+
{/* @ts-expect-error router is required! */}
31+
<Table
32+
data={[1, 2, 3]}
33+
renderRow={(row) => {
34+
type test = Expect<Equal<typeof row, number>>;
35+
return <tr />;
36+
}}
37+
/>
38+
39+
<WrappedTable
40+
data={[1, 2, 3]}
41+
renderRow={(row) => {
42+
type test = Expect<Equal<typeof row, number>>;
43+
return <tr />;
44+
}}
45+
/>
46+
47+
<WrappedTable
48+
data={[1, 2, 3]}
49+
renderRow={(row) => {
50+
type test = Expect<Equal<typeof row, number>>;
51+
return <tr />;
52+
}}
53+
/>
54+
</>;
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
import { Router, useRouter } from "fake-external-lib";
2+
import { Equal, Expect } from "../helpers/type-utils";
3+
4+
export const withRouter = <TProps extends { router: Router }>(
5+
Component: (props: TProps) => React.ReactNode,
6+
): ((props: Omit<TProps, "router">) => React.ReactNode) => {
7+
const NewComponent = (props: Omit<TProps, "router">) => {
8+
const router = useRouter();
9+
return <Component {...(props as TProps)} router={router} />;
10+
};
11+
12+
NewComponent.displayName = `withRouter(${
13+
(Component as { displayName?: string }).displayName
14+
})`;
15+
16+
return NewComponent;
17+
};
18+
19+
type TableProps<T> = {
20+
data: T[];
21+
renderRow: (item: T) => React.ReactNode;
22+
router: Router;
23+
};
24+
25+
export const Table = <T,>(props: TableProps<T>) => {
26+
return <table />;
27+
};
28+
29+
const WrappedTable = withRouter(Table);
30+
31+
<>
32+
{/* @ts-expect-error router is required! */}
33+
<Table
34+
data={[1, 2, 3]}
35+
renderRow={(row) => {
36+
type test = Expect<Equal<typeof row, number>>;
37+
return <tr />;
38+
}}
39+
/>
40+
41+
<WrappedTable
42+
data={[1, 2, 3]}
43+
renderRow={(row) => {
44+
type test = Expect<Equal<typeof row, number>>;
45+
return <tr />;
46+
}}
47+
/>
48+
49+
<WrappedTable
50+
data={[1, 2, 3]}
51+
renderRow={(row) => {
52+
type test = Expect<Equal<typeof row, number>>;
53+
return <tr />;
54+
}}
55+
/>
56+
</>;

0 commit comments

Comments
 (0)