Skip to content
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

Fix missing TypeScript return type for serverStreaming calls. #1167

Merged
18 changes: 9 additions & 9 deletions packages/grpc-web/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,11 +70,11 @@ declare module "grpc-web" {

export class MethodDescriptor<REQ, RESP> {
constructor(name: string,
methodType: any,
requestType: any,
responseType: any,
requestSerializeFn: any,
responseDeserializeFn: any);
methodType: string,
requestType: new (...args: unknown[]) => REQ,
responseType: new (...args: unknown[]) => RESP,
requestSerializeFn: (request: REQ) => Uint8Array,
responseDeserializeFn: (bytes: Uint8Array) => RESP);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you make the return type to match the Closure type definition here? The fact it's currently using Uint8Arry is implementation detail and should probably be omitted.

* @param {function(REQUEST): ?} requestSerializeFn

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not quite sure why it would make sense to have these typed as wither unknown or any - if we allow more values here consumers will be allowed to create MethodDescriptor instances which break internal invariants, e.g. I could create a MethodDescriptor with a serialize function which returns a number and typescript won't complain, but during runtime it will break. In my opinion MethodDescriptor is part of the public interface and thus the constructor should only allow valid values to be passed to the constructor. Nevertheless I can totally understand if you want it to return an interface / unknown instead, maybe it's just a matter of personal preference.

Copy link
Collaborator

@sampajano sampajano Nov 19, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if we allow more values here consumers will be allowed to create MethodDescriptor instances which break internal invariants

I get your sentiment in general.. Although because MethodDescriptor code is generated rather than specified by callers, this probably doesn't make a practical difference..

Nevertheless I can totally understand if you want it to return an interface / unknown instead, maybe it's just a matter of personal preference.

The main reason i want to keep this in sync with the Closure type annotation is that internally (Google) we're referring to the Closure type as source of truth, and only on Github we're also adding the TS type info. And because the internal types are subject to change, I don't want us to commit to stronger types in TS than we do in JS. If that makes sense :)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok sure, thanks for the explanation. I reverted the types of requestSerializeFn and responseDeserializeFn to any.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks a lot :)

createRequest(requestMessage: REQ,
metadata?: Metadata,
callOptions?: CallOptions): Request<REQ, RESP>;
Expand All @@ -83,10 +83,10 @@ declare module "grpc-web" {
status?: Status): UnaryResponse<REQ, RESP>;
getName(): string;
getMethodType(): string;
getResponseMessageCtor(): any;
getRequestMessageCtor(): any;
getResponseDeserializeFn(): any;
getRequestSerializeFn(): any;
getRequestMessageCtor(): new (...args: unknown[]) => REQ;
getResponseMessageCtor(): new (...args: unknown[]) => RESP;
getRequestSerializeFn(): (request: REQ) => Uint8Array;
getResponseDeserializeFn(): (bytes: Uint8Array) => RESP;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above :)

}

export class Request<REQ, RESP> {
Expand Down