unknown and Runtime Validation

Use unknown when a value's type is not known. Unlike any, unknown prevents unsafe operations until the value is narrowed. Data from JSON.parse, environment variables, local storage, files, and HTTP APIs should be considered untrusted unless a runtime contract is enforced.

A TypeScript interface disappears at runtime, so it cannot validate JSON by itself. Validate with explicit checks or a runtime schema library, then return a typed value only after validation succeeds. Keep validation at system boundaries rather than repeating it throughout trusted internal code.

Narrow unknown data
function isRecord(value: unknown): value is Record<string, unknown> {
  return typeof value === "object" && value !== null && !Array.isArray(value);
}

function readName(value: unknown): string | undefined {
  if (!isRecord(value)) return undefined;
  return typeof value.name === "string" ? value.name : undefined;
}
💡 The type predicate narrows the value to a string-keyed object with unknown values. The name property is then checked separately before it is returned as a string.
Key Takeaways
  • Prefer unknown over any at uncertain boundaries.
  • Static types do not validate JSON at runtime.
  • Validate once at boundaries and pass trusted values inward.
Knowledge Check

What is the key safety difference between `unknown` and `any`?