GoogleChromeLabs / GoogleChromeLabs/comlink
How should I handle optional exposed methods in TypeScript?
- Dominant language
- TypeScript
- Stars
- 12.8k
- Forks
- 435
- PR merge metrics
- No merged PRs in 30d
Description
I would like to expose a common interface for all my workers like this:
```ts
export interface WrappedWorker {
foo?: () => void;
}
```
And one of my workers implements it like this:
```ts
import * as Comlink from "comlink";
import type { WrappedWorker } from "./WrappedWorker.ts";
export class FooWorker implements WrappedWorker {
foo: () => "bar"
}
Comlink.expose(new FooWorker());
```
In my main thread, the wrapped worker will expose `foo` as `Remote<() => string> | Promise`, this causes two problems:
1. `await fooWorker?.foo();` causes lint error for when `foo` is `Promise`.
2. If I resolve the method getter promise before actually calling, comlink proxy will try to `.apply()` to `undefined` and throws. Option 1 throws this one too if `foo` is actually undefined at runtime.
```ts
const worker = new Worker("./WrappedWorker.ts");
const fooWorker = Comlink.wrap(worker);
// 1. Not all constituents of type 'Promise | Remote<() => Promisable>' are callable.
await fooWorker?.foo();
// 2. TypeError: Cannot read properties of undefined (reading 'apply')
const fooMethod = await fooWorker.foo;
await fooMethod?.();
```
Contributor guide
Assessment
This issue has not been assessed yet.