Skip to content

Commit cf5f14f

Browse files
committed
Added many more exercises
1 parent a9578b8 commit cf5f14f

13 files changed

Lines changed: 1374 additions & 1 deletion

package-lock.json

Lines changed: 1114 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,13 +143,15 @@
143143
"s-64": "tt-cli run 64 --solution"
144144
},
145145
"dependencies": {
146+
"@tanstack/react-query": "^4.29.12",
146147
"@types/express": "^4.17.13",
147148
"@types/react": "^18.2.8",
148149
"@types/react-dom": "^18.2.4",
149150
"express": "^4.18.1",
150151
"react": "^18.2.0",
151152
"react-dom": "^18.2.0",
152153
"react-hook-form": "^7.44.3",
154+
"react-select": "^5.7.3",
153155
"zod": "^3.17.10"
154156
}
155157
}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
import { useQuery } from "@tanstack/react-query";
2+
import { Equal, Expect } from "../helpers/type-utils";
3+
4+
interface User {
5+
fullName: string;
6+
job: string;
7+
}
8+
9+
const getUser = async (): Promise<User> => {
10+
return Promise.resolve({
11+
fullName: "Matt Pocock",
12+
job: "Developer",
13+
});
14+
};
15+
16+
/**
17+
* A bit of a hint to start with. useQuery has a LOT of overloads - but a lot
18+
* of them are disappearing in the next major version. The ones that'll be
19+
* sticking around are the first three.
20+
*
21+
* 1. How are the first three overloads different to the others? Put differently,
22+
* what's the thing that's similar about the first three that's different to
23+
* the other six?
24+
*/
25+
26+
useQuery;
27+
// ^ CMD+click on this to see the overloads
28+
29+
/**
30+
* 2. When you provide queryFn to useQuery, the type of query.data is inferred
31+
* as the return type of queryFn. Why is that?
32+
*/
33+
const query1 = useQuery({
34+
queryFn: getUser,
35+
});
36+
37+
// Without initialData, the type of query1.data is User | undefined
38+
type test1 = Expect<Equal<typeof query1.data, User | undefined>>;
39+
40+
/**
41+
* 3. When you provide initialData to useQuery, the type of query.data no longer
42+
* has undefined in it. Why is that?
43+
*/
44+
const query2 = useQuery({
45+
queryFn: getUser,
46+
initialData: {
47+
fullName: "",
48+
job: "",
49+
},
50+
});
51+
52+
// WITH initialData, the type of query.data is just User
53+
type test2 = Expect<Equal<typeof query2.data, User>>;
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import {
2+
QueryFunctionContext,
3+
QueryKey,
4+
useQuery,
5+
} from "@tanstack/react-query";
6+
import { useAuthToken } from "fake-external-lib";
7+
import { Equal, Expect } from "../helpers/type-utils";
8+
9+
const useApi = (
10+
queryKey: any[],
11+
queryFn: (key: any, token: string) => Promise<any>,
12+
) => {
13+
const token = useAuthToken();
14+
15+
return useQuery({
16+
queryFn: (ctx) => queryFn(ctx, token),
17+
queryKey,
18+
});
19+
};
20+
21+
// If you pass in an array of strings to queryFn, the type of ctx.queryKey
22+
// should be string[]
23+
const query = useApi(["users"], async (ctx, token) => {
24+
type tests = [
25+
Expect<Equal<typeof ctx.queryKey, string[]>>,
26+
Expect<Equal<typeof token, string>>,
27+
];
28+
29+
return Promise.resolve([
30+
{
31+
id: 1,
32+
name: "Matt Pocock",
33+
},
34+
]);
35+
});
36+
37+
// The type of query.data should be { id: number; name: string }[] | undefined
38+
type tests = [
39+
Expect<Equal<typeof query.data, { id: number; name: string }[] | undefined>>,
40+
];
41+
42+
// If you pass in an array of numbers in the queryKey, the type of ctx.queryKey
43+
// should be number[]
44+
useApi([1, 2], async (ctx, token) => {
45+
type test = Expect<Equal<typeof ctx.queryKey, number[]>>;
46+
});
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
import {
2+
QueryFunctionContext,
3+
QueryKey,
4+
useQuery,
5+
} from "@tanstack/react-query";
6+
import { useAuthToken } from "fake-external-lib";
7+
import { Equal, Expect } from "../helpers/type-utils";
8+
9+
const useApi = <TData, TQueryKey extends QueryKey>(
10+
queryKey: TQueryKey,
11+
queryFn: (
12+
key: QueryFunctionContext<TQueryKey>,
13+
token: string,
14+
) => Promise<TData>,
15+
) => {
16+
const token = useAuthToken();
17+
18+
return useQuery({
19+
queryFn: (ctx) => queryFn(ctx, token),
20+
queryKey,
21+
});
22+
};
23+
24+
// If you pass in an array of strings to queryFn, the type of ctx.queryKey
25+
// should be string[]
26+
const query = useApi(["users"], async (ctx, token) => {
27+
type tests = [
28+
Expect<Equal<typeof ctx.queryKey, string[]>>,
29+
Expect<Equal<typeof token, string>>,
30+
];
31+
32+
return Promise.resolve([
33+
{
34+
id: 1,
35+
name: "Matt Pocock",
36+
},
37+
]);
38+
});
39+
40+
// The type of query.data should be { id: number; name: string }[] | undefined
41+
type tests = [
42+
Expect<Equal<typeof query.data, { id: number; name: string }[] | undefined>>,
43+
];
44+
45+
// If you pass in an array of numbers in the queryKey, the type of ctx.queryKey
46+
// should be number[]
47+
useApi([1, 2], async (ctx, token) => {
48+
type test = Expect<Equal<typeof ctx.queryKey, number[]>>;
49+
});
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import ReactSelect from "react-select";
2+
import { Equal, Expect } from "../helpers/type-utils";
3+
4+
/**
5+
* 1. Try to figure out the types the props of the Select component should have,
6+
* including the generic types!
7+
*
8+
* Here's a clue: ReactSelect exports a type called 'Props'...
9+
*/
10+
export const Select = (props) => {
11+
return <ReactSelect {...props} />;
12+
};
13+
14+
interface Option {
15+
id: number;
16+
label: string;
17+
}
18+
19+
const guitarists: Option[] = [
20+
{
21+
id: 1,
22+
label: "Jimi Hendrix",
23+
},
24+
{
25+
id: 2,
26+
label: "Stevie Ray Vaughan",
27+
},
28+
];
29+
30+
<>
31+
<Select
32+
options={guitarists}
33+
onChange={(option) => {
34+
// It should infer the type of option!
35+
// If isMulti is false, it should NOT be an array
36+
type test = Expect<Equal<typeof option, Option | null>>;
37+
}}
38+
/>
39+
40+
<Select
41+
options={guitarists}
42+
isMulti
43+
onChange={(option) => {
44+
// If isMulti is true, it should be an array
45+
type test = Expect<Equal<typeof option, readonly Option[]>>;
46+
}}
47+
/>
48+
</>;
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
import ReactSelect, { GroupBase, Props } from "react-select";
2+
import { Equal, Expect } from "../helpers/type-utils";
3+
4+
/**
5+
* You need to mimic the exact type of the Props type exported by react-select.
6+
*/
7+
export const Select = <
8+
Option,
9+
IsMulti extends boolean = false,
10+
Group extends GroupBase<Option> = GroupBase<Option>,
11+
>(
12+
props: Props<Option, IsMulti, Group>,
13+
) => {
14+
return <ReactSelect {...props} />;
15+
};
16+
17+
interface Option {
18+
id: number;
19+
label: string;
20+
}
21+
22+
const guitarists: Option[] = [
23+
{
24+
id: 1,
25+
label: "Jimi Hendrix",
26+
},
27+
{
28+
id: 2,
29+
label: "Stevie Ray Vaughan",
30+
},
31+
];
32+
33+
<>
34+
<Select
35+
options={guitarists}
36+
onChange={(option) => {
37+
// If isMulti is false, it should NOT be an array
38+
type test = Expect<Equal<typeof option, Option | null>>;
39+
}}
40+
/>
41+
42+
<Select
43+
options={guitarists}
44+
isMulti
45+
onChange={(option) => {
46+
// If isMulti is true, it should be an array
47+
type test = Expect<Equal<typeof option, readonly Option[]>>;
48+
}}
49+
/>
50+
</>;
File renamed without changes.

src/08-external-libraries/65-reusable-form-library-with-zod.problem.tsx

Whitespace-only changes.
File renamed without changes.

0 commit comments

Comments
 (0)