-3
I am implementing a small crud using gRPC and typescript, my problem is: The self-generated stubs create a class and a "type" for each parameter in the protofile
. For example, the Userid parameter generates a class with getUserId, etc, and a namespace with "type" Userid.
The problem is that when I try to use the method in mine client
, typescript interprets the method parameter as the class and not the type.
So instead of getUsersById({id: 1}, callback)
... he asks me something like getUsersById(new UserId)
.
user. Proto:
syntax = "proto3";
package userServicePKG;
message User {
int32 id = 1;
string name = 2;
int32 age = 3;
}
message UserId {
int32 id = 1;
}
service UserService{
rpc getUserById (UserId) returns (User);
}
Userserviceclientpb.ts (Protobuf generated) - Function Definition
methodInfogetUserById = new grpcWeb.AbstractClientBase.MethodInfo(
User,
(request: UserId) => {
return request.serializeBinary();
},
User.deserializeBinary
);
getUserById(
request: UserId,
metadata: grpcWeb.Metadata | null): Promise<User>;
getUserById(
request: UserId,
metadata: grpcWeb.Metadata | null,
callback: (err: grpcWeb.Error,
response: User) => void): grpcWeb.ClientReadableStream<User>;
getUserById(
request: UserId,
metadata: grpcWeb.Metadata | null,
callback?: (err: grpcWeb.Error,
response: User) => void) {
if (callback !== undefined) {
return this.client_.rpcCall(
new URL('/userServicePKG.UserService/getUserById', this.hostname_).toString(),
request,
metadata || {},
this.methodInfogetUserById,
callback);
}
return this.client_.unaryCall(
this.hostname_ +
'/userServicePKG.UserService/getUserById',
request,
metadata || {},
this.methodInfogetUserById);
}
user_pb.d.ts (Protobuf Generated) - Defines types and Classes:
export class UserId extends jspb.Message {
getId(): number;
setId(value: number): UserId;
serializeBinary(): Uint8Array;
toObject(includeInstance?: boolean): UserId.AsObject;
static toObject(includeInstance: boolean, msg: UserId): UserId.AsObject;
static serializeBinaryToWriter(message: UserId, writer: jspb.BinaryWriter): void;
static deserializeBinary(bytes: Uint8Array): UserId;
static deserializeBinaryFromReader(message: UserId, reader: jspb.BinaryReader): UserId;
}
export namespace UserId {
export type AsObject = {
id: number,
}
}
Client.Vue:
const client = new UserServiceClient('http://localhost:5001', null, null);
let userId = { id:1 };
client.getUserById(userId, function (error: grpcWeb.Error, response: any) {
//do something
});
The userid parameter causes the following error:
Argument of type '{ id: number; }' is not Assignable to Parameter of type 'Userid'. Type '{ id: number; }' is Missing the following properties from type 'Userid': getId, setId, serializeBinary, toObject, and 8 more. Vetur(2345)
It seems to me that typescript deduces that the first parameter getUserById
is the type Class UserId
and not the kind that comes from namespace UserId
.
Is there anything I can do about it? Since it was self-generated code by grpc_web, it should interpret correctly right? Oh it is not a mistake of mine in the implementation of gRPC or misuse of typescript.
Thanks in advance!
Thank you for indicating problems with the question too, thank you.
– user94991
The answer is in the error message. When you do this
let userId = { id:1 };
client.getUserById(userId, function (error: grpcWeb.Error, response: any) {
 //do something
});
this variableuserId
is not an instance ofUserId
and therefore cannot be passed as a parameter to this function. Create a class instance, as a reader I cannot do this because the question does not provide enough information to instantiate the classUserId
does not show the constructor and I know 5 libs that have the typejspb.Message
, thatUserId
drift and all different, making it impossible to answer.– Augusto Vasques
@Augustovasques Thank you so much for your help,
jspb.Message
comes from the following importimport * as jspb from "google-protobuf"
, will help in something?– user94991
The manual says to instantiate and not subclass
jspb.Message
. You’ll have to modify the function.– Augusto Vasques