ts-brand is a TypeScript library that enables nominal typing through 'type branding,' a technique that intersects a base type with an object type containing a non-existent property. This allows developers to create distinct types (e.g., `PostId`, `UserId`) from a common primitive (like `number`), preventing accidental assignment bugs at compile time even though they share the same runtime representation. The library is currently at version 0.2.0, indicating it's an early-stage but active project. It ships with TypeScript types inherently, as its functionality is entirely type-system based. A key differentiator is its emphasis on ensuring brand uniqueness, offering methods like using recursive interface types as branding to prevent accidental conflation of brands across different definitions, which is a common pitfall in simpler branding implementations. The project's release cadence appears to be driven by contributions, without a fixed schedule.
npm install ts-brandVerified import paths — ran on the pinned version, not inferred.
This quickstart demonstrates how to define and use branded types for nominal typing, preventing common ID-mismatch bugs at compile time. It shows the `Brand` type in action, including recursive branding for enhanced uniqueness.
Do not rely on branded types for runtime type checks. Implement runtime validation or assertion functions separately if needed.
Use a unique branding type, such as a string literal specific to the context (e.g., `'UserId'`), or for stronger guarantees, use the recursive branding pattern where the branding type refers to its own interface (e.g., `Brand<number, User>`).
Review TypeScript's release notes for breaking changes and adjust type assertions or branded type definitions as necessary, especially when `strictNullChecks` or other strict compiler options are enabled. Consider using assertion functions to encapsulate type checks.
Monitor the project's GitHub repository for updates and review changelogs carefully before upgrading to newer versions. Pin exact versions in your `package.json` to mitigate unexpected changes.
Use a type assertion (`as Brand<number, 'User'>`) to explicitly tell TypeScript that the value conforms to the branded type after validation, or use a utility function that performs the assertion and returns the branded type. `const myUserId: User['id'] = rawNumber as User['id'];`
This is the intended behavior of nominal typing. If you genuinely need to convert between distinct branded types, explicitly 'unbrand' to the base type and then 'rebrand' to the target type, typically with a type assertion and appropriate validation logic. E.g., `const convertedUserId: User['id'] = (postAuthorId as number) as User['id'];`
Ensure you are using `import { Brand } from 'ts-brand';` within a TypeScript file (`.ts` or `.tsx`). If working in a mixed JavaScript/TypeScript project, remember that types are a compile-time construct and not available at runtime via `require`.No dependency data recorded yet.