Categories


Archives


Recent Posts


Categories


TypeScript won’t Save us

astorm

Frustrated by Magento? Then you’ll love Commerce Bug, the must have debugging extension for anyone using Magento. Whether you’re just starting out or you’re a seasoned pro, Commerce Bug will save you and your team hours everyday. Grab a copy and start working with Magento instead of against it.

Updated for Magento 2! No Frills Magento Layout is the only Magento front end book you'll ever need. Get your copy today!

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.

Copyright © Alan Storm 1975 – 2020 All Rights Reserved

Originally Posted: 4th May 2020