TYPESCRIPT / CHAPTER 14
Unknown input and trustworthy results
AdvancedConnect runtime validation to accurate static contracts.
By the end of this chapter
- Use unknown for unvalidated values
- Validate shape before field access
- Return a discriminated success or failure result
The idea
Unknown accepts arbitrary incoming values while preventing unchecked operations on them. This makes it a useful boundary type for parsed data or external messages. Narrow the value with real runtime checks: exclude null, establish an object shape, and check the types and domain rules of required fields. An assertion merely tells the checker to trust you and cannot replace those checks.
Validation can return a discriminated result instead of throwing when malformed input is an ordinary expected outcome. The success variant carries a fresh validated record; the failure variant carries an explanation. Keep the validator’s promised type aligned with every condition it actually tests. Exercise missing fields, wrong types, and invalid numeric values, because a successful check becomes a fact that downstream code depends on.
type CountResult = {ok: true; count: number} | {ok: false; error: string};
function parseCount(value: unknown): CountResult {
if (typeof value !== "number" || !Number.isInteger(value) || value < 0) {
return {ok: false, error: "Expected a nonnegative integer"};
}
return {ok: true, count: value};
}
console.log(parseCount(4).ok);true
The number check enables numeric operations, while integer and range checks establish domain validity. The returned variant explicitly communicates whether validation succeeded.
Try it yourself
Validate an unknown object with string id and finite score, returning a result union with a fresh success record.
Use your own editor for this exercise. Runnable challenges on CodeQuest are available for JavaScript, Python, and SQL.
CHECK YOUR UNDERSTANDING