Values and types: build a value inspector
Hands-on project — build a small value inspector that stores bytes once and decodes them under several type rules, then demonstrates JS number precision and coercion with evidence.
You have read that one bit pattern means different things under different type rules. Now make it concrete: write a small program that stores a byte once and shows you what it becomes under each rule — then push JS numbers to where their single 64-bit format starts to show.
Turn the unit’s mental model into a working tool: store raw bytes, decode the same bytes under several type rules, and demonstrate with real output that meaning lives in the reading, not the bits — including where IEEE 754 storage and coercion bite.
Build a small command-line value inspector in TypeScript or JavaScript (Node, Deno, or Bun) that stores raw bytes in a buffer, decodes the same bytes under several type rules, and prints a side-by-side report proving that the bits never change while the interpretation does — then extend it to demonstrate the limits of the single JS number type.
- Running the program prints a labelled report where the same byte appears once but is decoded into at least three different values, with the original bit pattern shown so a reader can see the bits did not change.
- The 4-byte region is decoded as both an integer and a float from one unchanged buffer, with both outputs and the shared bytes visible.
- The typeof section prints all five everyday primitives and explicitly flags that typeof null is 'object', with a note that the correct null test is x === null.
- The precision and coercion sections each print the actual runtime output (not a guessed value) alongside a one-line explanation grounded in 'one 64-bit IEEE 754 number type' and 'per-operator coercion'.
- Add a 'wrong-type' demo: write bytes that are a valid integer, deliberately read them as a float (and vice versa), and show the nonsense value to make the cost of misinterpretation concrete.
- Add a tiny static-vs-dynamic comparison: write one snippet that fails to compile under TypeScript strict mode (e.g. const x: number = '9.99') and the equivalent JS that runs and silently coerces, and capture both outcomes in your README.
- Support little-endian vs big-endian for the 4-byte read (DataView accepts a flag) and show how byte order changes the decoded integer while the stored bytes stay the same.
- Extend the inspector to decode a 2-byte region as a signed vs unsigned 16-bit integer and show how the same bits become a negative or positive number under two's-complement vs plain place-value.
This is the unit made executable: you stored bytes once and watched them become an integer, a character, a colour channel, and a float depending only on the rule you applied — proof that meaning is in the reading. You also met the edges of JS’s single number type (0.1 + 0.2, the safe-integer ceiling) and saw coercion pick a type rule for you per operator. Build the inspector once and “bits have no inherent meaning” stops being a slogan and becomes something you have seen with your own output.
Something unclear?
Ask a question about this lesson. Questions are anonymous and go straight to the author to make the lesson better.