Posts

Announcing TypeScript Type Guards

TypeScript is excellent at telling you what you meant to pass around. Runtime is excellent at reminding you that expectations are not a security boundary. I published TypeScript Type Guards as a small utility package for …

April 2, 2026 2 min read 318 words

In this article

TypeScript is excellent at telling you what you meant to pass around.

Runtime is excellent at reminding you that expectations are not a security boundary.

I published TypeScript Type Guards as a small utility package for narrowing unknown values without rewriting the same little checks in every project.

Why This Exists

This sits in the same general trust-and-guardrails bucket as my ESLint Zero-Tolerance AI anti-slop rules, but at a different layer.

Lint rules stop bad patterns from getting comfortable.

Type guards help your code stop pretending runtime data is already trustworthy.

If you work with API responses, config files, plugin boundaries, JSON blobs, message payloads, or anything that enters the system wearing an unknown trench coat, you eventually need to ask:

What is this thing, actually?

And then you need that answer to narrow cleanly in TypeScript.

The Package

Install it with:

npm install @coderrob/typescript-type-guards

Then use the guards directly:

import {
  createEnumGuard,
  isArrayOf,
  isDefined,
  isNonEmptyString,
  isPlainObject,
  isString,
} from "@coderrob/typescript-type-guards";

const values: unknown = ["Ada", "Grace", "Barbara"];

if (isArrayOf(isString)(values)) {
  values.map((value) => value.toUpperCase());
}

const maybeConfig: unknown = { mode: "strict" };

if (isPlainObject(maybeConfig) && isNonEmptyString(maybeConfig.mode)) {
  console.log(maybeConfig.mode);
}

enum Status {
  Active = "ACTIVE",
  Inactive = "INACTIVE",
}

const isStatus = createEnumGuard(Status, "Status");

if (isStatus("ACTIVE")) {
  console.log("valid status");
}

The current package includes primitive guards, numeric guards, collection guards, object-like guards, and utility helpers like isDefined, createTypeGuard, and createEnumGuard.

It ships a single public entrypoint with both ESM and CommonJS support, because nobody needs another package that turns module resolution into a side quest.

The Point

This is not trying to be a giant validation framework.

It is a set of reusable, boring, predictable checks for the moments where TypeScript needs a little runtime evidence before it should believe you.

Small tool. Sharp edge. Fewer hand-rolled typeof value === "string" rituals scattered across the codebase like little offerings to the compiler.

-Rob