Brands a base type T with a phantom tag B to create a nominal type.
Two Brand<string, 'UserId'> and Brand<string, 'Email'> are structurally
identical strings at runtime, but TypeScript treats them as distinct types
at the call site — preventing accidental mix-ups.
Use a const-assertion cast at the creation boundary:
type UserId = Brand<string, 'UserId'>;
const toUserId = (s: string): UserId => s as UserId;
Available since v3.0.0
import type { Brand } from '@helpers4/type';
// or, from the all-in-one package (same code, one install):
import type { Brand } from 'helpers4/type';
type Brand<T, B extends string> = T & { readonly __brand: B }
type Meter = Brand<number, 'Meter'>;
type Second = Brand<number, 'Second'>;
declare function speed(distance: Meter, time: Second): number;
const d = 100 as Meter;
const t = 5 as Second;
speed(d, t); // ✅
speed(t, d); // ✗ Type error — args swapped
View source on GitHub