REACT Contents

Avoiding any and Unsafe Casts

Treat any and unsafe casts as production defects. Replace assertions with validation and narrowing, enforce boundary checks, and remove unknown as T patterns that hide runtime failures.

On this page

Why any Is a Production Problem

  • any disables safety and allows invalid states to flow through the system.
  • Most runtime crashes in typed apps are caused by boundary casts and unchecked external data.
  • Production rule: no any at boundaries and no unknown as T without validation.

Common Sources of any

  • JSON parsing and API responses.
  • Third party libraries without types.
  • Loose event handler signatures.
  • Incremental migrations that never removed temporary casts.

Replace Casts with Narrowing

function isRecord(x: unknown): x is Record<string, unknown> {
  return typeof x === "object" && x !== null;
}

function getString(x: Record<string, unknown>, k: string): string {
  const v = x[k];
  if (typeof v !== "string") throw new Error("invalid");
  return v;
}

Example: Safe Parsing Pattern

type UserVM = { id: string; name: string };

function parseUserVM(x: unknown): UserVM {
  if (!isRecord(x)) throw new Error("invalid");
  return { id: getString(x, "id"), name: getString(x, "name") };
}

Operational Controls

  • Enable strict TypeScript settings.
  • Use lint rules to ban explicit any.
  • Centralize parsing and mapping at API boundaries.
  • Fail fast on invalid data with explicit error state.

Failure Modes

  • unknown as T used as a shortcut and invalid data enters UI state.
  • Any spreads through props and reduces type signal across the tree.
  • Runtime crashes occur far from the source, making incidents hard to debug.

Incident Triage Checklist

  • Search for any, unknown as, and large type assertions.
  • Inspect API boundary mapping functions.
  • Add runtime guards where data enters the system.
  • Convert boolean soup to unions to restore invariants.