Deserialization
| Start from unknown | |
| Guard every field | |
| Nested objects | |
| Arrays of records |
Start from unknown
Data from JSON, files, or the network arrives without a compile time type. Parse it into unknown first, which forces every reader to prove the shape before use.
JSON.parse returns any, so assign the result to an unknown binding right away. From that point the checker blocks property access until a guard passes.
const data: unknown = JSON.parse("{\"ok\":true}");
console.log(data);
Guard every field
A guard is a small function that answers one question, such as whether a value is a string. Combine tiny guards to describe bigger shapes without writing one giant check.
Return plain booleans at first and upgrade to type predicates later. Even boolean guards document the expected shape and centralize every runtime check.
function isString(value: unknown): boolean {
return typeof value === "string";
}
const flag: boolean = isString("hi");
console.log(flag);
Nested objects
Objects need checks for their container shape before any field check. Reject null and non objects early, then test for the presence of each required key.
Write the guard as a type predicate so a passing check narrows the value for the rest of the scope. Later code then reads fields with full editor support.
type User = {
name: string;
};
function isUser(value: unknown): value is User {
if (typeof value !== "object") {
return false;
}
if (value === null) {
return false;
}
return "name" in value;
}
Arrays of records
Arrays add one more layer: prove the value is an array, then guard each element. Collect the elements that pass and skip or report the rest.
Loop with a plain for of, push matching items into a typed result array, and return it. Callers receive clean records and never touch raw unknown again.
// User and isUser from above
function allUsers(values: Array<unknown>): Array<User> {
const found: Array<User> = [];
for (const item of values) {
if (isUser(item)) {
found.push(item);
}
}
return found;
}
Next: Capstone: todo CLI
Article author: Arthur Isaev