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 Promise
s!
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
tsTry
constmethods = {add (a : number,b : number): number {returna +b },}
and in the main application you’d have access to some object with an add
automatically (after a connection is established).
tsTry
child .add (3, 4)
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-bdoAsyncThing: (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-stickcd 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
- Make sure to brush up on mapped types, conditional types and use of the
infer
keyword - Familiarize yourself with the
Parameters<T>
andReturnType<T>
utility types