@@ -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+ */
0 commit comments