Question presented to candidate:
"TypeScript is structurally typed, so a UserId and an OrderId that are both strings can be swapped by accident. How would you make the compiler tell them apart, and what does that cost at run time?"
What a strong answer should cover:
- Structural typing: two aliases of
stringare the same type, so aliases alone give no protection - A brand intersects the base type with a fake property,
string & { readonly __brand: "UserId" }, so plain strings and other brands are no longer assignable - Brands are created in one place, a smart constructor or a type guard / assertion function that validates and then casts, so the type means "already checked"
- The brand is type-only: zero run-time cost, the value is still a normal string (
typeofis"string"), and operations like.trim()or+return the unbranded base type - A
unique symbolkey and a genericBrand<T, B>helper make brands harder to fake and reusable; units of measure (Meters,Seconds) are a classic use - Alternatives and neighbours: classes with a
#privatefield are nominal, string enums are opaque, and validation libraries offer brand helpers
Code / implementation expected: Yes β define two branded ID types, a constructor for each, and show a call that swaps them failing to compile.