Objects
Primitive values in JavaScript can be composed into Plain-Old-JavaScript-Objects. This can be
easily represented using the bin.struct() schema constructor function.
Structs
Section titled “Structs”import * as bin from 'typed-binary';
// Simple object schemaconst Person = bin.struct({ firstName: bin.string, lastName: bin.string, age: bin.i32,});
// Writing a PersonPerson.write(writer, { firstName: 'John', lastName: 'Doe', age: 43,});
console.log(JSON.stringify(Person.read(reader))); // { "firstName": "John", ... }Inferring the type
Section titled “Inferring the type”The type of values a struct reads can be extracted with bin.ExtractOut, and the type of values it accepts when writing
with bin.ExtractIn. The latter is a readonly version of the former, so that readonly data can be written too.
type Person = bin.ExtractOut<typeof Person>;// ^? { firstName: string, lastName: string, age: number }Extending structs
Section titled “Extending structs”bin.concat creates a struct with the properties of all the passed in structs, in order.
const Employee = bin.concat([Person, bin.struct({ salary: bin.u32 })]);// { firstName: string, lastName: string, age: number, salary: number }Tagged unions
Section titled “Tagged unions”bin.union describes a value that can take one of several shapes (variants), depending on a tag
that is encoded before it. For example, if you want to store an animal description, certain animal
types might have differing features from one another.
import * as bin from 'typed-binary';
const Animal = bin.union( // The tag, encoded first bin.orderedEnum('dog', 'cat'), // The properties of each variant, keyed by the value of the tag { dog: { breed: bin.string }, cat: { striped: bin.bool }, }, // Properties shared by all variants, encoded right after the tag { base: { nickname: bin.string, age: bin.i32 } },);
// Writing an AnimalAnimal.write(writer, { type: 'cat', // We're specifying which variant we want this object to be.
// Base properties nickname: 'James', age: 5,
// Variant specific properties striped: true,});
// Deserializing the animalconst animal = Animal.read(reader);
// -- Type checking works here! --// animal.type => 'dog' | 'cat'if (animal.type === 'cat') { // animal.striped => boolean console.log(animal.striped ? 'Striped' : 'Not striped');} else { // animal.breed => string console.log(`More specifically, a ${animal.breed}`);
// This would result in a type error (Static typing FTW!) // console.log(`Striped: ${animal.striped}`);}The tag can be any schema whose values key the variants:
| Tag | Encoding |
|---|---|
bin.orderedEnum('dog', 'cat') |
The index of the value, in a single byte |
bin.prefixEnum('dog', 'cat') |
The ASCII characters of the value |
bin.u8, bin.u16, … |
The number itself, e.g. for variants keyed by a TypeScript enum |
bin.string |
A null-terminated string |
The property holding the tag is called type by default, and can be renamed with the key option:
bin.union(tag, variants, { key: 'kind' }).