Learn TypeScript w/ Mike North

Challenge 4: Penpal types

March 22, 2022

Table of Contents

The Challenge

Years ago I was doing some work that involved Web Workers. If you’ve never used these before, you can think of them as totally independent programs that communicate with your “main” program via the postMessage API.

postMessage is great (and a good example of the actor concurrency model) but it’s not the most refined way to handle asynchronous communication. Frankly, I prefer Promises!

Thankfully I found this cool open source project called Penpal, which effectively allows you to define methods in your worker, and they appear in your main application async-ified.

For example, in your worker you might have

ts
const methods = {
add(a: number, b: number): number {
return a + b
},
}
Try

and in the main application you’d have access to some object with an add automatically (after a connection is established).

ts
child.add(3, 4)
(property) add: (a: number, b: number) => Promise<number>
Try

If the way this works is not quite clear to you, I recommend taking a look at the readme for the library

The task

Create a utility type WrapForPenpal<T> that takes an object T with methods (you may assume no non-function properties are ever on this object), and emits a type with similar methods, but any non-promise return types become ”Promise-ified”.

For example

ts
let methods = {
add: (a: number, b: number) => a+b,
subtract: (a: number, b: number) => a-b
doAsyncThing: (url: string): Promise<string[]>
}
const asyncMethods: WrapForPenpal<typeof methods> = {}
asyncMethods.add(a, b); // returns Promise<number>
asyncMethods.subtract(a, b); // returns Promise<number>
asyncMethods.doAsyncThing('/api/thing'); // Promise<string[]>

You do not need to worry about actually creating an object that has these Promise-ified methods — we are only interested in the utility type.

Setup

First, if you haven’t done so already, clone the workshop project for this course

sh
git clone https://github.com/mike-north/making-typescript-stick
cd making-typescript-stick

Make sure you have Volta installed. If you haven’t done so already, just run the following to install it

sh
curl https://get.volta.sh | bash

Next, let’s install our dependencies

sh
yarn

and finally, let’s navigate to the folder containing this specific challenge

sh
cd challenges/async-communicator

Your job is to modify the code in ./src/index.ts until all of the existing tests within the same file pass.

Hints



© 2023 All Rights Reserved