JAVASCRIPT / CHAPTER 17
Validate data at boundaries
AdvancedDesign transformations around explicit contracts and invariants.
By the end of this chapter
- Validate parsed values before using their shape
- Separate malformed input from valid empty input
- Explain correctness using invariants and edge cases
The idea
Data crossing a boundary deserves validation even when its source is usually trustworthy. JSON.parse checks JSON syntax, not your application schema. A parsed value can be null, a number, or an object with missing fields. Validate the outer shape and each required property before applying a transformation. Keep validation close to the boundary so internal code can rely on a narrower contract.
A robust design distinguishes invalid input from a valid empty result. Define whether malformed records are rejected or reported, and avoid silently manufacturing plausible values. State an invariant for the transformation, such as every accepted score being finite and nonnegative. Test absent properties, zero, invalid types, and nested changes. Independent pure functions make these cases easier to inspect than a single routine that parses, mutates, and prints.
function readScore(value) {
if (typeof value !== "number" || !Number.isFinite(value) || value < 0) {
throw new TypeError("Expected a finite nonnegative score");
}
return value;
}
console.log(readScore(0));0
The guard rejects wrong types, infinities, NaN, and negatives while preserving valid zero. The return value satisfies the function’s stated invariant.
Try it yourself
Validate an array of records with string id and finite score, then return a new highest-score record or null for an empty array.
Use your own editor for this exercise. Runnable challenges on CodeQuest are available for JavaScript, Python, and SQL.
Open JavaScript coding challengesCHECK YOUR UNDERSTANDING