Safety
Advanced
Runtime Validation and Schema Boundaries
Design safe boundaries between TypeScript and untrusted JSON, queues, webhooks, storage, and vendor SDKs.
48 min
3 sections
runtime-validation
schema
unknown
boundaries
1
2
3
01. The Compile-time vs Runtime Line
Section 1 of 3
TypeScript proves facts about code you compile. It does not prove that an API response, webhook body, localStorage value, queue message, or feature flag service returned the shape you expected. Enterprise apps need a repeatable boundary strategy: accept unknown, validate once, convert to trusted types, then keep the rest of the app strongly typed.
typescript
type ParseResult<T> =
| { ok: true; value: T }
| { ok: false; issues: string[] };
type VendorSubscriptionEvent = {
id: string;
type: "subscription.created" | "subscription.cancelled";
customerId: string;
occurredAt: string;
};
function parseSubscriptionEvent(input: unknown): ParseResult<VendorSubscriptionEvent> {
if (typeof input !== "object" || input === null) {
return { ok: false, issues: ["Expected object"] };
}
const record = input as Record<string, unknown>;
const issues: string[] = [];
if (typeof record.id !== "string") issues.push("id must be a string");
if (record.type !== "subscription.created" && record.type !== "subscription.cancelled") {
issues.push("type must be a known subscription event");
}
if (typeof record.customerId !== "string") issues.push("customerId must be a string");
if (typeof record.occurredAt !== "string") issues.push("occurredAt must be an ISO string");
if (issues.length > 0) return { ok: false, issues };
return {
ok: true,
value: {
id: record.id as string,
type: record.type as VendorSubscriptionEvent["type"],
customerId: record.customerId as string,
occurredAt: record.occurredAt as string,
},
};
}Exercise
Validate a queue message
Practice
Create a parser for a queue message that provisions a tenant. It should validate orgId, requestedBy, plan, and traceId and return structured validation issues.
Back to Course