Skip to content

Worker.postMessage missing optional options parameter #31448

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
dasa opened this issue May 17, 2019 · 8 comments · Fixed by microsoft/TypeScript-DOM-lib-generator#703 or #31557
Closed
Assignees
Labels
Bug A bug in TypeScript Needs More Info The issue still hasn't been fully clarified

Comments

@dasa
Copy link

dasa commented May 17, 2019

TypeScript Version: 3.5.0-rc

Search Terms:

Worker MessagePort postMessage

Code

let worker: Worker;
worker.postMessage("test");

let port: MessagePort;
port.postMessage("test");

let either: MessagePort | Worker;
either.postMessage("test"); //  error TS2554: Expected 2 arguments, but got 1.

Expected behavior:

No error. There is no error in 3.4. I'm not sure if this is a bug in the compiler or due to the changes to MessagePort.postMessage in lib.dom.d.ts. Should Worker.postMessage also be updated to have the optional options parameter?

Reference: https://html.spec.whatwg.org/multipage/workers.html#dedicated-workers-and-the-worker-interface

Actual behavior:

error TS2554: Expected 2 arguments, but got 1.

@RyanCavanaugh RyanCavanaugh added the Bug A bug in TypeScript label May 17, 2019
@RyanCavanaugh RyanCavanaugh added this to the TypeScript 3.5.0 milestone May 17, 2019
@sandersn
Copy link
Member

The problem is that MessagePort has two overloads for postMessage, the second of which has transfer, but transfer isn't optional there. If you change it to optional in the second overload, there's no error.

On the other hand, reading through the spec leads me to this interface:

interface DedicatedWorkerGlobalScope : WorkerGlobalScope {
  [Replaceable] readonly attribute DOMString name;

  void postMessage(any message, sequence<object> transfer);
  void postMessage(any message, optional PostMessageOptions options);

  void close();

  attribute EventHandler onmessage;
  attribute EventHandler onmessageerror;
};

sequence<object> transfer doesn't look optional to me, especially in comparison to the optional PostMessageOptions options on the next line. Perhaps the spec is wrong here?

@sandersn sandersn added the Needs More Info The issue still hasn't been fully clarified label May 20, 2019
@fatcerberus
Copy link

I'm confused though: despite the non-optional transfer, shouldn't the call with only one argument still match the postMessage(any message, optional PostMessageOptions options) case?

@sandersn
Copy link
Member

@fatcerberus I believe the code that creates a signature from a union of signatures is stricter about the number of required parameters in the resulting signature.

Here's a standalone version that's easier to paste into the playground:

interface Terable {
    a,b,c
}
interface PostMessageOptions {
    transferable: Terable[]
}
interface MsgPort {
    postMessage(message: any, options?: PostMessageOptions): void;
    postMessage(message: any, transfer: Terable[]): void;
}
interface Wrkr {
    postMessage(message: any, transfer?: Terable[]): void;
}
declare let either: MsgPort | Wrkr;
either.postMessage('test')

@dasa
Copy link
Author

dasa commented May 21, 2019

@fatcerberus
Copy link

fatcerberus commented May 21, 2019

@sandersn Oh I see - Worker is missing the options overload. My comment above was based on a reading of the spec in which Worker and MessagePort have the same two overloads for postMessage. So yeah, same question as @dasa above me - why is the second overload missing from Worker?

@sandersn
Copy link
Member

Looks like @saschanaz just missed it in microsoft/TypeScript-DOM-lib-generator#679. That PR has overrides for MessagePort, ServiceWorker and DedicatedWorkerGlobalScope, but not Worker.

I think it's correct to add it for Worker too, but I want to find out how @saschanaz determined those 3 were the ones that got the overrides before I do.

@sandersn
Copy link
Member

Here's the link for Worker. I'll go ahead and add it in TSJS-lib-generator.

@sky0014
Copy link

sky0014 commented Feb 17, 2020

@sandersn Maybe the transfer param should be optional? I found this in the spec:

dedicatedWorkerGlobal.postMessage(message [, transfer ])
dedicatedWorkerGlobal.postMessage(message [, { transfer } ])

And now I still got an error while pass only one param, I have to change it to

worker.postMessage('message', undefined);

that is not a good practice

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug A bug in TypeScript Needs More Info The issue still hasn't been fully clarified
Projects
None yet
5 participants