A tiny invariant function for runtime assertions with TypeScript type narrowing
npx @tessl/cli install tessl/npm-tiny-invariant@1.3.0Tiny Invariant is a lightweight assertion library that provides a single invariant function for runtime validation with TypeScript type narrowing. It serves as a minimal alternative to the larger invariant library, offering essential assertion functionality with automatic message stripping in production builds for optimal bundle size.
npm install tiny-invariantimport invariant from "tiny-invariant";For CommonJS:
const invariant = require("tiny-invariant");import invariant from "tiny-invariant";
// Basic assertion
invariant(value, "Expected value to be truthy");
// Type narrowing example
const maybeUser: User | null = getUser();
invariant(maybeUser, "Expected user to exist");
// maybeUser is now typed as User (null eliminated)
// Lazy message evaluation
invariant(condition, () => getExpensiveErrorMessage());The core invariant function provides runtime assertion with TypeScript type narrowing capabilities.
/**
* Asserts that the condition is truthy, throwing an error if falsy.
* In TypeScript, acts as an assertion function to narrow types.
* Messages are automatically stripped in production builds.
*
* @param condition - Value to test for truthiness
* @param message - Optional error message or lazy message function
* @throws Error when condition is falsy
*/
function invariant(
condition: any,
message?: string | (() => string)
): asserts condition;Type Narrowing Behavior:
T | null | undefined)Error Behavior:
Error("Invariant failed: <message>") or Error("Invariant failed") if no messageError("Invariant failed") (custom messages stripped for bundle size)Message Options:
invariant(condition, "Custom error message")invariant(condition, () => computeExpensiveMessage())invariant(condition) (uses default "Invariant failed")Usage Examples:
// Null checking with type narrowing
function processUser(user: User | null) {
invariant(user, "User must be provided");
// user is now typed as User, not User | null
console.log(user.name); // TypeScript knows user is not null
}
// Value validation
function divide(a: number, b: number) {
invariant(b !== 0, "Division by zero is not allowed");
return a / b;
}
// Lazy message for expensive operations
function validateConfig(config: unknown) {
invariant(
isValidConfig(config),
() => `Invalid config: ${JSON.stringify(config, null, 2)}`
);
}
// Boolean narrowing
function handleFlag(flag: boolean) {
invariant(flag, "Flag must be true to continue");
// TypeScript knows flag is true here
}
// Array/object existence checking
function processItems(items: Item[] | undefined) {
invariant(items && items.length > 0, "Items array must not be empty");
// items is now typed as Item[] (undefined and empty array eliminated)
return items.map(processItem);
}Tiny Invariant is designed for production optimization:
process.env.NODE_ENV to determine behaviorRecommended Build Configuration:
For optimal production bundles, use build tools that:
process.env.NODE_ENV to "production"babel-plugin-dev-expression for additional optimizationThe package exports a single default function with TypeScript assertion signature:
declare function invariant(
condition: any,
message?: string | (() => string)
): asserts condition;
export default invariant;Key Type Features:
asserts condition: TypeScript assertion function signature for type narrowingcondition: any: Accepts any value for maximum flexibilitymessage?: string | (() => string): Optional string or lazy function messagevoid with assertion signature for type narrowing side effects