Type-Safe Assertion Library for TypeScript

1.0.9 · active · verified Tue Apr 21

typed-assert is a lightweight, zero-dependency assertion library designed specifically for TypeScript 3.7+ environments. It leverages TypeScript's assertion functions feature to perform runtime checks that simultaneously narrow types at compile-time, promoting the use of `unknown` for untrusted input instead of `any`. The library provides a suite of common assertion functions (`isString`, `isNumber`, `isRecord`, etc.) and combinators (`isArrayOf`, `isOneOf`, `isOption`), allowing developers to build robust type guards and custom composite assertions. As of version 1.0.9, it's a stable release with no explicit major release cadence, but it's actively maintained. A key differentiator is its compile-time type narrowing alongside runtime validation, contrasting with traditional assertion libraries like Chai or Jest's `expect` which primarily offer runtime validation without type inference benefits. For more complex schema validation needs, the documentation explicitly recommends considering `zod` as an alternative due to `typed-assert`'s simpler scope.

Common errors

Warnings

Install

Imports

Quickstart

Demonstrates defining a custom type assertion for a complex interface and its application to untrusted `unknown` input, showcasing compile-time type narrowing.

import * as t from 'typed-assert';

interface Config { 
  readonly a: { 
    readonly b: 'c';
    readonly d: string; 
  };
  readonly f?: number;
}

// Custom assertion function for a complex type
function assertConfig(input: unknown): asserts input is Config {
  t.isRecordWithKeys(input, ['a']); // 'f' is optional, so not required here
  t.isRecordWithKeys(input.a, ['b', 'd']);
  t.isExactly(input.a.b, 'c');
  t.isString(input.a.d);
  t.isOption(input.f, t.isNumber); // Handles optional numeric property
}

// Example usage with untrusted input
const untrustedInput1: unknown = {
  a: { b: 'c', d: 'hello' },
  f: 123
};

assertConfig(untrustedInput1);
// At this point, untrustedInput1 is narrowed to Config
console.log(untrustedInput1.a.d); // 'hello'

const untrustedInput2: unknown = {
  a: { b: 'c', d: 456 } // 'd' should be string
};

try {
  assertConfig(untrustedInput2);
} catch (error: any) {
  console.error(`Assertion failed: ${error.message}`); 
  // Expected: 'Value must be a string: 456'
}

view raw JSON →