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

Generated Service Definition types are inaccurate #1740

Closed
mintchkin opened this issue Apr 6, 2021 · 2 comments · Fixed by #1745
Closed

Generated Service Definition types are inaccurate #1740

mintchkin opened this issue Apr 6, 2021 · 2 comments · Fixed by #1745

Comments

@mintchkin
Copy link

Problem description

The typescript generator introduced in #1474 produces an incorrect/incomplete type for services in loaded protos. Referencing the golden-generated output, the type of the service field is ServiceDefinition.

This causes problems with the type of server.addService in the native grpc package:

const packageDefinition = (protoLoader.loadSync(...) as unknown) as ProtoGrpcType;
const server = new grpc.Server();
server.addService(
    packageDefinition.google.showcase.v1beta1.Echo.service,
    // ~~~~~~ TS: Argument of type 'ServiceDefinition' is not assignable to parameter of type 'ServiceDefinition<{ Block: ..., Chat: ..., ...}>'
    { Block: ..., Chat: ..., ... }
)

I think the type can be improved without changing the generated code much by injecting a custom ServiceDefinition type based on the one in the native grpc package, or maybe the related one in @grpc/proto-loader could just be replaced instead.

type ServiceDefinition<
  ImplementationType extends grpc.UntypedServiceImplementation = grpc.UntypedServiceImplementation
> = {
  [K in keyof ImplementationType]: MethodDefinition<
    Parameters<ImplementationType[K]>[0], // Request Type
    ReturnType<ImplementationType[K]> // Return Type
  >;
};

// ... later in e.g. echo.ts

Echo: SubtypeConstructor<typeof grpc.Client, _google_showcase_v1beta1_EchoClient> & { service: ServiceDefinition<EchoHandlers> }

Environment

  • @grpc/proto-loader@0.6.0
@murgatroid99
Copy link
Member

One solution here may be to loosen the type parameter in the native grpc package to avoid this kind of problem. That current type may not even be correct in all cases.

Another good alternative may be to explicitly generate the service definition type along with each service implementation type. In your suggestion you are using generics to extract the service definition type from the implementation type, but we can take advantage of the fact that the details of the implementation type are known at generation time.

So, it would be something like this in google/showcase/v1beta1/Echo.ts:

export interface EchoServiceDefinition {
  Block: MethodDefinition<_google_showcase_v1beta1_BlockRequest__Output, _google_showcase_v1beta1_BlockResponse>,
  // etc.
}

It would even be possible to go a step further and generate the exact contents of each method definition as a type.

@murgatroid99
Copy link
Member

This has been fixed in version 0.6.1, with types similar to the example code I put in my previous comment.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants