Testing & Code Quality

Runtime Validation

Runtime validation checks actual values while the program runs. It complements TypeScript by proving that untrusted input matches the type the rest of the code wants to use.
  • Validation is runtime evidence
  • Parsing is better than checking-and-continuing
  • Validation should report useful errors
  • Schemas reduce type drift
  • Validate as close to the boundary as possible
Small parser function
type User = { id: string; name: string }

function parseUser(value: unknown): User {
  if (typeof value !== "object" || value === null) {
    throw new Error("User must be an object")
  }

  const candidate = value as { id?: unknown; name?: unknown }
  if (typeof candidate.id !== "string") throw new Error("User.id must be string")
  if (typeof candidate.name !== "string") throw new Error("User.name must be string")

  return { id: candidate.id, name: candidate.name }
}
Manual parsing is fine for small shapes; schema libraries help as shapes grow.
Validation results
StyleShapeUse when
Throwing parserreturns T or throwsInvalid input is exceptional at this layer
Result parsersuccess/error unionCaller should recover or report multiple errors
Boolean guardvalue is TSimple branching
Assertion functionasserts value is TAbort current path on invalid input
Sources
  • Effective TypeScript, 2nd EditionRuntime checking
  • The TypeScript Handbookunknown and narrowing
  • The Modern JavaScript TutorialError handling