TypeScript
How the types of a worker are inferred, how to name them, and how to describe a worker you did not write with defineWorker.
One type crosses the threads
The worker file exports the type of what defineWorker returns. That type is the only thing the main thread
imports.
import { defineWorker } from 'easy-web-worker/defineWorker';
const fibonacci = (n: number): number =>
n <= 1 ? n : fibonacci(n - 1) + fibonacci(n - 2);
// every key of the returned object is a method of the worker
const worker = defineWorker(() => ({ fibonacci }));
// the main thread only needs this type
export type MathWorker = typeof worker;Use import type, so the bundler never pulls the code of the worker into the main bundle.
Name the worker object
WorkerProxy<TWorker> is the type of what createWorker returns. Use it for fields, props and parameters.
import { createWorker, type WorkerProxy } from 'easy-web-worker/createWorker';
import workerUrl from '../getting-started/math.worker?worker&url';
import type { MathWorker } from '../getting-started/math.worker';
// the type of what createWorker returns, for fields, props and parameters
let math: WorkerProxy<MathWorker> | null = null;
export const getMath = () =>
(math ??= createWorker<MathWorker>(workerUrl, {
workerOptions: { type: 'module' },
}));
export const compute = (worker: WorkerProxy<MathWorker>) => worker.fibonacci(40);The message in a plain function
A plain function receives the message as second parameter, but TypeScript cannot infer its type there. Either
wrap the method with onMessage, or annotate it with WorkerMethodMessage<TPayload>.
import { defineWorker, type WorkerMethodMessage } from 'easy-web-worker/defineWorker';
// a plain function can type its message by hand
const count = (to: number, message: WorkerMethodMessage<number>) => {
message.reportProgress(100);
return to;
};
const worker = defineWorker(() => ({ count }));
export type CounterWorker = typeof worker;Describe a worker you did not define
The generic of createWorker also accepts a plain description of the methods. It fits workers written with the
message API, or built outside your project.
import { createWorker } from 'easy-web-worker/createWorker';
import workerUrl from './static.worker?worker&url';
// typed methods on top of a worker written with the message api
export const worker = createWorker<{ uppercase: (text: string) => string }>(workerUrl, {
workerOptions: { type: 'module' },
});
export const upper = worker.uppercase('hello'); // CancelablePromise<string>Good to know
strict: required payloads are enforced withstrictorstrictNullChecks. Without it, every payload is optional.- Rejections are
unknown: the reason of a rejected or canceled call is typedunknown. Narrow it before reading it. - One name is taken: a method cannot be called
then. The worker object is not a promise, soawait workernever sends a message. - Merged workers: with an array of functions, write the array inline or declare it
as const, so each function keeps its own type.