Skip to content

Commit a83143b

Browse files
committed
Added stretch goals to wrapExternalLib
1 parent aa0e8b1 commit a83143b

File tree

2 files changed

+78
-8
lines changed

2 files changed

+78
-8
lines changed

exercises/03-wrapExternalLib.exercise.ts

Lines changed: 56 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,7 @@ export const fetchUserWithFullName = async (
1919
...args: Parameters<typeof fetchUser>
2020
): Promise<Awaited<ReturnType<typeof fetchUser>> & { fullName: string }> => {
2121
/**
22-
* 💡 Ouch, that's a lot of generics in a row. Discuss among
23-
* your group what you think this big mess of generics means.
22+
* 💡 Ouch, that's a lot of generics in a row.
2423
*/
2524
const user = await fetchUser(...args);
2625
return {
@@ -47,26 +46,28 @@ export const fetchUserWithFullName = async (
4746
* 💡 This is our first intro to generic code - and a lot of it
4847
* can look like this: Something<SomethingElse<Wow<Deeper<Ok>>>>.
4948
*
50-
* 🧑‍💻 There's a reason we went for this approach. Take a look at
51-
* the type definitions for external-lib.
49+
* 🧑‍💻 There's a reason we went for this approach. There's something
50+
* annoying about the type definitions for external-lib.
5251
*
5352
* 🔮 Do a go-to-definition on fetchUser:
5453
*
5554
* import { fetchUser } from "external-lib";
5655
* ^ 🔮
5756
*
58-
* You'll see that the only type definition here is a single function.
59-
* There isn't any code like this:
57+
* You'll see that the only type definition here is a single
58+
* function. There aren't any type defs for the return types
59+
* or parameters of the functions. I.e:
6060
*
61-
* interface User {
61+
* interface FetchUserReturnType {
6262
* id: string;
6363
* firstName: string;
6464
* lastName: string;
6565
* age: number;
6666
* }
6767
*
6868
* This is an issue, because we need that information if we're going
69-
* to extend it with `& { fullName: string }`.
69+
* to extend it with `& { fullName: string }` for our wrapper
70+
* function.
7071
*/
7172

7273
/**
@@ -85,6 +86,8 @@ export const fetchUserWithFullName = async (
8586
/**
8687
* 🛠 We can extract the value of the promise with Awaited:
8788
*
89+
* https://www.typescriptlang.org/docs/handbook/release-notes/typescript-4-5.html#the-awaited-type-and-promise-improvements
90+
*
8891
* type FetchUserReturnType = Awaited<ReturnType<typeof fetchUser>>;
8992
* ^ 🚁
9093
*
@@ -128,6 +131,7 @@ export const fetchUserWithFullName = async (
128131
* 🧑‍💻 There's one more thing to think about, too. We're currently only
129132
* using one function from 'external-lib', fetchUser. But that's because
130133
* we're at the start of the project.
134+
*
131135
* We'll likely end up using 10-12 functions from that lib, so this code
132136
* might be duplicated many times if we want to add extra parameters to
133137
* the output.
@@ -384,3 +388,47 @@ export const fetchUserWithFullName = async (
384388
* We've also seen how some clever inference can get you out of
385389
* tight spots when library typings aren't terribly helpful.
386390
*/
391+
392+
/**
393+
* 🕵️‍♂️ Stretch goal 1: Create a fetchPostWithMeta function which:
394+
*
395+
* Calls fetchPost and adds
396+
*
397+
* { meta: { title: title, description: body } }
398+
*
399+
* to the output.
400+
*
401+
* Use the existing WrapFunction to give it a type definition.
402+
*
403+
* Solution #1
404+
*/
405+
406+
const fetchPost = (id: string) => {
407+
return Promise.resolve({
408+
id,
409+
title: "Title",
410+
body: "Great post",
411+
});
412+
};
413+
414+
/**
415+
* 🕵️‍♂️ Stretch goal 2: Given the function below, get a union
416+
* type of all of its parameters.
417+
*
418+
* Solution #2
419+
*/
420+
421+
const funcWithManyParameters = (
422+
a: string,
423+
b: string,
424+
c: number,
425+
d: boolean,
426+
) => {
427+
return [a, b, c, d].join(" ");
428+
};
429+
430+
type FuncParamsAsUnion = any;
431+
/** ^ 🚁
432+
*
433+
* 🚁 This should be string | number | boolean
434+
*/
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
/**
2+
* #1
3+
*
4+
* const fetchPostWithMeta: WrapFunction<
5+
* typeof fetchPost,
6+
* { meta: { title: string; description: string } }
7+
* > = async (...args) => {
8+
* const post = await fetchPost(...args);
9+
*
10+
* return {
11+
* ...post,
12+
* meta: {
13+
* title: post.title,
14+
* description: post.body,
15+
* },
16+
* };
17+
* };
18+
*
19+
* #2
20+
*
21+
* type FuncParamsAsUnion = Parameters<typeof funcWithManyParameters>[number];
22+
*/

0 commit comments

Comments
 (0)