GoogleChromeLabs / comlink

Comlink makes WebWorkers enjoyable.
Apache License 2.0
11.37k stars 390 forks source link

Typescript RemoteObject does not allow assignment of non-promise value #483

Open egriff38 opened 4 years ago

egriff38 commented 4 years ago

The following code does not appear to compile using comlink@4.3.0

type RA = Remote<{foo:string}>
declare const a: RA
a.foo = "bar"

On account of a.foo being a Promise<string> and "bar" being a string. I understand there's currently no way to allow separate setter and getter types, but it seemed like the code worked differently before moving to 4.3.0?

surma commented 4 years ago

Ah that’s an interesting case. @felixfbecker WDYT? I don’t think we have thought about setting values and I am actually not sure if current TS lets us solve this.

felixfbecker commented 4 years ago

Yeah that is interesting and I don't know how TypeScript could be twisted to allow this. The only possible option would be assinging a Promise (but comlink would need to handle that):

type RA = Remote<{foo:string}>
declare const a: RA
a.foo = Promise.resolve("bar")

Maybe the properties should be marked readonly otherwise.

The obvious workaround of course is to expose an explicit setter function.

Personally, I find the Promise-wrapped getter/setter quite unhelpful (I've never needed them) and a bit confusing to say the least (because they break the principle of a property being the value you assigned it right after assigning it). It would actually be more helpful to me personally if comlink's default behavior with non-function, non-proxy-marked properties of proxied objects was to copy them at proxy time so that they are available synchronously (with no way to set them across the thread other than through methods). Currently I instead just define a lot of pure data interfaces that can be cloned and lift all methods up to the parent object.