I was following the quickstart document to implement the hello world client server example in TypeScript.
I can compile and run the code fine if I have noImplicitAny set to false in tsconfig.json. However, if I have it set to true, I get the following error when running tsc -p .:
node_modules/grpc/index.d.ts:2:55 - error TS7016: Could not find a declaration file for module 'protobufjs'. '.../grpc-example/node_modules/protobufjs/dist/protobuf.js' implicitly has an 'any' type.
Try `npm install @types/protobufjs` if it exists or add a new declaration (.d.ts) file containing `declare module 'protobufjs';`
2 import { Message, Service as ProtobufService } from "protobufjs";
~~~~~~~~~~~~
Also, running npm install @types/protobufjs does not resolve the issue.
Try: npm install @types/[email protected]
After using npm install @types/[email protected], compilation reports the following errors:
> tsc -p .
node_modules/@grpc/proto-loader/build/src/index.d.ts:42:40 - error TS2694: Namespace 'ProtoBuf' has no exported member 'IParseOptions'.
42 export declare type Options = Protobuf.IParseOptions & Protobuf.IConversionOptions & {
~~~~~~~~~~~~~
node_modules/@grpc/proto-loader/build/src/index.d.ts:42:65 - error TS2694: Namespace 'ProtoBuf' has no exported member 'IConversionOptions'.
42 export declare type Options = Protobuf.IParseOptions & Protobuf.IConversionOptions & {
~~~~~~~~~~~~~~~~~~
node_modules/@types/protobufjs/index.d.ts:275:16 - error TS2304: Cannot find name 'XMLHttpRequest'.
275 XHR(): XMLHttpRequest;
~~~~~~~~~~~~~~
src/client.ts:19:33 - error TS2339: Property 'Greeter' does not exist on type 'Message | GrpcObject | typeof Client'.
Property 'Greeter' does not exist on type 'Message'.
19 const client = new helloProto.Greeter('localhost:50051',
~~~~~~~
src/server.ts:26:32 - error TS2339: Property 'Greeter' does not exist on type 'Message | GrpcObject | typeof Client'.
Property 'Greeter' does not exist on type 'Message'.
26 server.addService(helloProto.Greeter.service, {
~~~~~~~
Based on in person feedback from @kjin, I installed protobufjs. This solved the issue since protobufjs includes type definitions.
Note that I still had the errors below. However, this is expected since, IIUC, the types from the proto file are not automatically annotated on the helloProto object created. Thus it is necessary to explicitly cast it to the correct type to instruct TypeScript of its type.
rc/client.ts:19:33 - error TS2339: Property 'Greeter' does not exist on type 'Message | GrpcObject | typeof Client'.
Property 'Greeter' does not exist on type 'Message'.
19 const client = new helloProto.Greeter('localhost:50051',
~~~~~~~
src/server.ts:26:32 - error TS2339: Property 'Greeter' does not exist on type 'Message | GrpcObject | typeof Client'.
Property 'Greeter' does not exist on type 'Message'.
26 server.addService(helloProto.Greeter.service, {
~~~~~~~
You shouldn't need to have an explicit dependency on protobufjs, and I don't understand why it helps here. The initial error indicates that the protobufjs package is present, but TypeScript is for some reason looking at a .js file instead of the .d.ts file.
@DominicKramer were you able to solve the compile error? The only solution I could come up with was casting helloProto to any, but then I lose my type checking
Same, I'd love to know the solution for this. I've been stuck in an loop of Google searches. This is the closest setup I have been able to mimic: https://medium.com/attest-engineering/fully-typed-typescript-api-consuming-grpc-and-graphql-5d5ae6b33bf1
Not TypeScript... but I ended up generating static code:
https://github.com/grpc/grpc/tree/master/examples/node/static_codegen
@murgatroid99 it appears the typescript definitions aren't available in the 5.x release of protobufjs, which this depends on. The typescript definitions are available in the 6.x releases.
The proto-loader package is set to a newer version already:
But the grpc-native-core is still pegged to an old version:
Oddly, this comment and object lead me to believe the module was already developed with v6 but that package.json just wasn't updated:
I did not realize Protobuf.js did not include type definitions. The correct course of action here is probably to include a dependency on @types/[email protected].
The dependency on Protobuf.js version 5 is deliberate. Bumping the dependency to version 6 would cause breaking changes in gRPC itself. This is part of why @grpc/proto-loader exists: to make that upgrade without breaking anything.
@murgatroid99 like this? https://github.com/grpc/grpc-node/pull/828
Yes. I don't know if that will solve the whole problem, but I think that's probably a good idea.
It seems to fix the above issue in my local test, but there are other issues.
Since @grpc/proto-loader is on v6 of protobufjs, the types aren't aligned and there are type errors related to that (e.g. Type 'Message' is not generic and Namespace ... has no exported member 'IParseOptions').
Unfortunately the native package will probably have to be updated or we'll have to stick to old versions to use it with Typescript.
That's going to be tricky to reconcile. There is an inherent ambiguity in importing protobufjs and wanting to get the actual type information from one version of the @types/protobufjs package instead of a different version of the protobufjs package. And the fact is that we can't change either of those versions.
Any progress here? Seems like most developers who would be using gRPC are also highly likely to be using Typescript as well
I have a possible fix in #1008
I have published version 1.23.3 with that fix. Please try it and see if it helps.
This fix in 1.23.3 works for me but has been undone in 1.23.4 it seems ?
I don't see that dependency in 1.23.4.
Sorry my mistake, I meant 1.24.0 - the fix is only in 1.23.3 and 1.23.4 and using 1.24.0 results in the error posted originally
I don't see that dependency on 1.24.0 either.
Strange, I see the import {...} from "protobufjs" (that causes the error) back in 1.24.0 as shown by
wget -qO - $(npm view [email protected] dist.tarball) | tar xzO package/index.d.ts | grep import
whereas in 1.23.4 (and 1.23.3) it is not there
wget -qO - $(npm view [email protected] dist.tarball) | tar xzO package/index.d.ts | grep import
Am I missing something ? Thanks :)
No, you're right. I was looking for the wrong thing. I guess that fix didn't make it into the 1.24 branch. I'll get a fix for that out soon.
Great, thanks :)
Version 1.24.1 is out with that fix.
Ok, many thanks !
Version 1.24.1 is out with that fix.
@murgatroid99 I'm still facing that with the following dependencies:
"dependencies": {
"@grpc/proto-loader": "^0.5.5",
"@types/express": "^4.17.9",
"@types/protobufjs": "^6.0.0",
"google-protobuf": "^3.14.0",
"grpc": "^1.24.4"
}
You explicitly added a dependency on @types/protobuf.js version 6.x. Since grpc depends on protobufjs version 5.x as mentioned previously in this issue, that is probably creating a compatibility problem.
You explicitly added a dependency on
@types/protobuf.jsversion 6.x. Sincegrpcdepends onprotobufjsversion 5.x as mentioned previously in this issue, that is probably creating a compatibility problem.
Thanks
hello. I'm able to compile the server but not the hello world client as I'm getting this error:
Property 'Greeter' does not exist on type 'ProtobufTypeDefinition | GrpcObject | ServiceClientConstructor'.
Property 'Greeter' does not exist on type 'ProtobufTypeDefinition'.ts(2339)