Branded Types for Nominal Identity

Attach a phantom brand to primitive types so structurally identical identifiers such as UserId and OrderId cannot be mixed up.

TypescriptData Integrity

Code

snippet
declare const brand: unique symbol;

export type Brand<T, B extends string> = T & { readonly [brand]: B };

export type UserId = Brand<string, "UserId">;
export type OrderId = Brand<string, "OrderId">;

export function asUserId(value: string): UserId {
  if (!/^usr_[a-z0-9]+$/.test(value)) throw new Error("invalid user id");
  return value as UserId;
}

export function loadUser(id: UserId): void {
  console.log("loading user", id);
}

const orderId = "ord_1" as OrderId;
// loadUser(orderId); // compile error: OrderId is not UserId