Syntax
declare const idBrand: unique symbol;
type UserId = string & { readonly [idBrand]: true };Examples
Branded Types for Validated Domain Values: working example
Run this standalone example after compiling with TypeScript 5.4+ in strict mode, targeting ES2022. Expected result: The program prints Lookup user_42; plain strings require validation before use.
declare const userIdBrand: unique symbol;
type UserId = string & { readonly [userIdBrand]: true };
function userId(value: string): UserId {
if (!/^user_[0-9]+$/.test(value)) throw new Error("Invalid user ID");
return value as UserId;
}
function describe(id: UserId): string { return `Lookup ${id}`; }
console.log(describe(userId("user_42")));
// describe("user_42"); // Type error: plain strings are not branded.- Expected result: The program prints Lookup user_42; plain strings require validation before use.
- The unique symbol marker distinguishes this domain type during checking.
- No symbol property is attached at runtime; the factory verifies the chosen invariant before asserting the brand.
Best practices
- Keep brand assertions inside small audited factories.
- Revalidate untrusted values after deserialization because types are erased.
Runtime & versions
Compiled to JavaScript. Feature availability depends on the language and runtime version used by your project; consult the official reference below.
TypeScript Handbook