A few weeks ago I started working with gRPC for the first time. These days gRPC stands for “general-purpose remote procedure call”, but I still think of it as “Google remote procedure call”, as it’s a project that came out of, and is primarily maintained, by Google engineers. It’s a system for building APIs, similar to SOAP or REST, that allows you to invoke a function that’s on another computer. It sits somewhere between REST and SOAP in terms of complexity and formalness, and I might have more to say about it later.
What I wanted to mention today was a bit of code I found in one of the GRPC libraries. This is a class in the @grpc/grpc-js
package, which is written in TypeScript and delivered as compiled javascript. Here’s the excerpted code I’m interested in
export class ServerDuplexStreamImpl<RequestType, ResponseType> extends Duplex
implements ServerDuplexStream<RequestType, ResponseType> {
/* ... */
}
At first, TypeScript is doing what it does. We get a ServerDuplexStreamImpl
class — and not some janky syntactic sugar over a javascript constructor function — this is a True Proper OOP Class™ with an interface to implement and some Generics thrown in to boot.
And then javascript rears it’s dynamic head and we get this
ServerDuplexStreamImpl.prototype._read =
ServerReadableStreamImpl.prototype._read;
ServerDuplexStreamImpl.prototype._write =
ServerWritableStreamImpl.prototype._write;
ServerDuplexStreamImpl.prototype._final =
ServerWritableStreamImpl.prototype._final;
ServerDuplexStreamImpl.prototype.end = ServerWritableStreamImpl.prototype.end;
My guess is this was written by a C++ programmer who’s used to having multiple inheritance at their disposal. Here the programmer wanted ServerDuplexStreamImpl
objects to have methods that inherited both from NodeJS’s built in Duplex
class, as well as methods from their own ServerWritableStreamImpl
class. Since TypeScript doesn’t offer multiple inheritance, the engineer fell back to older, proven javascript techniques and just added some methods directly to the ServerDuplexStreamImpl
prototype (because despite TypeScript offering True Proper OOP Classes™, it’s still just javascript at the end of the day)
So, as much as TypeScript can offer developers-used-to-a-type-system some type safety, at the end of the day you’re still dealing with a loosely typed language that uses a prototype based inheritance system. TypeScript can help you box your code in, but other people are going to use it to box their code in differently, and you’ll need to be ready for that.