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);
JSON is nice for two reasons:
- You can read it (
{"direction":"up","distance":1000}is pretty explicit). - 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;
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;
}
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 }
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)