DEV Community

Andrew Morris
Andrew Morris

Posted on

How to Speak Binary in TypeScript

If you're sending or receiving data in TypeScript, chances are high that you are using JSON:

const awesomeData = {
  direction: 'up',
  distance: 1000,
};

const json = JSON.stringify(awesomeData);

send(json);
Enter fullscreen mode Exit fullscreen mode

JSON is nice for two reasons:

  1. You can read it ({"direction":"up","distance":1000} is pretty explicit).
  2. JSON doesn't take anything to set up, it's just there.

However, this simple utility doesn't play very nicely with TypeScript:

const json = receive();

// { direction:'up', distance: 1000 }
const awesomeData = JSON.parse(json);

// TypeScript compiler: "Sure, why not?"
awesomeData.direction = 1;
Enter fullscreen mode Exit fullscreen mode

JSON.parse is one of those APIs that opts out of type checking - it returns any, which means TypeScript knows nothing about it, but will let us do anything with it.

That's not cool. We're using TypeScript to avoid exactly this problem.

There is a better way:

import * as tb from 'typed-bytes';

const Awesome = tb.object({
  direction: tb.enum_('up', 'down', 'left', 'right'),
  distance: tb.size,
});

type Awesome = tb.TypeOf<typeof Awesome>;

function sendData() {
  const awesomeData: Awesome = {
    direction: 'up',
    distance: 1000,
  };

  // Here encodeBuffer knows that awesomeData needs to match type Awesome
  const buffer = tb.encodeBuffer(Awesome, awesomeData);

  send(buffer);
}

function receiveData() {
  const buffer = receive();

  const awesomeData = tb.decodeBuffer(Awesome, buffer);

  // Error: Type '1' is not assignable to type '"up" | "down" | "left" | "right"'
  awesomeData.direction += 1;
}
Enter fullscreen mode Exit fullscreen mode

Hooray, now awesomeData is correctly type checked 🎉.

It's not just that though. Take a closer look at buffer:

ArrayBuffer { [Uint8Contents]: <00 e8 07>, byteLength: 3 }
Enter fullscreen mode Exit fullscreen mode

Three bytes. That's all we needed. In JSON we used 34 bytes.

Why not just use Protocol Buffers?

I'm glad you asked. typed-bytes is a public domain library that lives at typedbytes.org. There's a detailed comparison over there 😉.

Top comments (0)