@variablesoftware/vs-brand-utils
v0.2.5
Published
🛡️🧩🏷️ Nominal (branded) TypeScript types & helpers for opaque types.
Maintainers
Readme
@variablesoftware/vs-brand-utils 🏷️🧩🛡️
Nominal (branded) TypeScript types & helpers for safe opaque types.
🏷️🧩🛡️ Type-safe branding for primitives and objects in TypeScript.
Usage Guide
See the Usage Guide for practical examples and patterns.
API Reference
See the API Reference for a summary of all exports and detailed documentation.
🔧 Installation
pnpm add @variablesoftware/vs-brand-utils🚀 Usage
import {
Brand,
brand,
isBrand,
assertBrand,
unbrand,
createBrand,
brandArray,
unbrandArray,
brandMany
} from "@variablesoftware/vs-brand-utils";
// Define a branded type
export type UserId = Brand<"UserId", string>;
// Brand a value
const id = brand<"UserId", string>("UserId", "abc123");
// Type-safe: cannot assign UserId to string or vice versa
// const s: string = id; // Type error
// const id2: UserId = 'plainstring'; // Type error
// Type guard
if (isBrand("UserId", id)) {
// id is UserId here
}
// Assert
assertBrand("UserId", id);
// Unbrand
const raw: string = unbrand("UserId", id);
// Brand an array
const brandedArr = brandArray("UserId", ["a", "b"]);
// Unbrand an array
const arr: string[] = unbrandArray("UserId", brandedArr);
// Brand many values
const many = brandMany("UserId", "a", "b");
// Factory for a specific brand
const TenantId = createBrand<"TenantId", string>("TenantId");
const tid = TenantId.brand("t-123");✨ Features
- 🏷️ Nominal/opaque types for primitives and objects
- 🧩 Type-safe branding and unbranding helpers
- 🛡️ Compile-time enforcement: prevents accidental mixing of branded and unbranded types
- Array helpers for batch branding/unbranding
- Factory for reusable brand helpers
- Zero runtime cost: all checks are type-level
- 100% test and code coverage (see
tests/unit/for split test suites) - Edge-case and runtime safety for all helpers
🎯 Goals
- Prevent accidental mixing of IDs, tokens, and other primitives
- Enable safe domain modeling with TypeScript
- No runtime overhead or dependencies
- Simple, composable API
- Fully documented and tested
🧪 Test Coverage
Tested using vitest with coverage for:
- Branding and unbranding
- Type guards and assertions
- Compile-time type errors
- Array helpers
- Edge cases and runtime behaviors
Test suites are organized by concern:
runtime-branding.test.tscompile-type-errors.test.tshelpers-and-factory.test.tsedge-cases.test.tsmissing-marker-edge-cases.test.ts
Run tests:
pnpm test📦 Modular Structure (vNext)
As of May 2025, the codebase is split into focused modules for maintainability and tree-shaking:
core– core types and internal symbolsbrand– branding helpers (brand,brandArray,brandMany)typeguards– type guard helpers (isBrand)assert– assertion helpers (assertBrand)unbrand– unbranding helpers (unbrand,unbrandArray)factory– thecreateBrandfactory for a bundled API
You can import everything from the main entry point:
import { brand, isBrand, assertBrand, unbrand, createBrand } from "@variablesoftware/vs-brand-utils";Or, for advanced usage and smaller bundles, import only what you need:
import { brand } from "@variablesoftware/vs-brand-utils/brand";
import { isBrand } from "@variablesoftware/vs-brand-utils/typeguards";All helpers are still available via the main package import for convenience.
🧪 Test Coverage & Code Structure
- All helpers and edge cases are tested for 100% coverage.
- See
src/for the modular implementation. - See
tests/unit/for split test suites by concern.
🚧 Status
This package is under active development and not yet stable.
Once stable, it will be published as:
"@variablesoftware/vs-brand-utils": "^0.8.0"📄 License
MIT © Rob Friedman / Variable Software
Built with ❤️ by @variablesoftware
Thank you for downloading and using this project. Pull requests are warmly welcomed!
🌐 Inclusive & Accessible Design
- Naming, logging, error messages, and tests avoid cultural or ableist bias
- Avoids assumptions about input/output formats or encodings
- Designed for clarity, predictability, and parity with TypeScript best practices
- Works well in diverse, multilingual, and inclusive developer environments
