microsoft / TypeScript

TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
https://www.typescriptlang.org
Apache License 2.0
100.75k stars 12.46k forks source link

tsserver protocol is missing notification message type. (maybe?) #37821

Open tomasgvivo opened 4 years ago

tomasgvivo commented 4 years ago

While implementing a tsserver client, I found out not all request messages will reply with a response. For example, the open request extends the Request interface. But it really notifies (as the documentation implies). This was a bit confusing for me, because I understood that if I send an open request, I must wait for the response... but it never came. https://github.com/microsoft/TypeScript/blob/a2609b1f1b58f9b6ef62cb3b6ff47efb35059eee/lib/protocol.d.ts#L1113-L1124

I understand that the interface documentation says the server will not send a response. I didn't read the full command documentation until now. But maybe the documentation could be a bit more explicit about a kind of message where a response is not expected, for certain commands (maybe notify?).

DanielRosenwasser commented 4 years ago

I've run into this too, so has @uniqueiniquity. It's very confusing to me that in our API that there's no acknowledgement that an open request succeeds just for the sake of consistency, so I ended up with a bunch of bugs where

await tsserverClient.open(...)

would just hang the process because both the client and my own code were implemented naively.

That said, I don't know how to fix it at this point...

tomasgvivo commented 4 years ago

Something very similar happened to me. I think modifying the protocol to call it a notification instead of a request will make things more clear.

RyanCavanaugh commented 4 years ago

@sheetalkamat thoughts?

sheetalkamat commented 2 years ago

We could make this kind of change:

export interface Request<_Response extends Response | void> extends Message {
        type: "request";

        /**
         * The command to execute
         */
        command: string;

        /**
         * Object containing arguments for the command
         */
        arguments?: any;
    }
    export type NoResponseRequest = Request<void>;
    export interface ReloadProjectsRequest extends NoResponseRequest {
        command: CommandTypes.ReloadProjects;
    }
    export interface OrganizeImportsRequest extends Request<OrganizeImportsResponse> {
        command: CommandTypes.OrganizeImports;
        arguments: OrganizeImportsRequestArgs;
    }