2

I'm using node to communicate with a gRPC server, here is an example of generated request ts

export class GetUserByFQDNRequest extends jspb.Message { 
    getEnvironmentId(): string;
    setEnvironmentId(value: string): void;

    getFqdn(): string;
    setFqdn(value: string): void;


    serializeBinary(): Uint8Array;
    toObject(includeInstance?: boolean): GetUserByFQDNRequest.AsObject;
    static toObject(includeInstance: boolean, msg: GetUserByFQDNRequest): GetUserByFQDNRequest.AsObject;
    static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
    static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
    static serializeBinaryToWriter(message: GetUserByFQDNRequest, writer: jspb.BinaryWriter): void;
    static deserializeBinary(bytes: Uint8Array): GetUserByFQDNRequest;
    static deserializeBinaryFromReader(message: GetUserByFQDNRequest, reader: jspb.BinaryReader): GetUserByFQDNRequest;
}

export namespace GetUserByFQDNRequest {
    export type AsObject = {
        environmentId: string,
        fqdn: string,
    }
}

and we are creating and sending a request in the following way:

 const request = new users.GetUserByFQDNRequest();
 request.setEnvironmentId(environmentId);
 request.setFqdn(fqdn);
 usersServiceClient.getUserByFQDN(request, setTimeout(timeoutMilliseconds), (err: ServiceError | null, response: users.GetUserByFQDNResponse)

I'm looking for a way to use the RequestType.AsObject type to create a request, for example:

 const request: GetUserByFQDNRequest.AsObject = {environmentId: "envID", fqdn: "fqdn"};

but unfortunately I can't use it in my usersServiceClient.getUserByFQDN since I'm getting the following error:

TS2345: Argument of type 'AsObject' is not assignable to parameter of type 'GetUserByFQDNRequest'

in the generated ts file there is a static method which convert the request to AsObject:

static toObject(includeInstance: boolean, msg: GetUserByFQDNRequest): GetUserByFQDNRequest.AsObject;

but sadly not the other way around.

Is there any way to convert AsObject to a request class without building a converter for each type of a gRPC request?

Or Yaacov
  • 3,597
  • 5
  • 25
  • 49
  • Essentially what you need is to describe a generic `interface` for a message class which depends on the type of the message. With the new typescript template literal types https://www.typescriptlang.org/docs/handbook/2/template-literal-types.html we can require getter and setter methods in the interface based on the names of the properties of the object. I'm working on this and I'm almost there, but one of the things that's tripping me up is that `AsObject` exists on the `namespace` rather than the `class`. – Linda Paiste Jan 29 '21 at 21:36
  • It just occurred to me that I think I can get the `AsObject` type for a class from its `toObject` return type. I am hoping to have a generic `convertObject` function that takes the `class` as an argument along with the data object and returns an instance of that class. – Linda Paiste Jan 29 '21 at 21:39
  • I think the types themselves are good but I started using them in an implementation and it's a mess. So I need to step away from this, but here's where I'm at: https://tsplay.dev/4w1dkW – Linda Paiste Jan 29 '21 at 22:12

0 Answers0