Brands distinguish otherwise identical primitive types in internal APIs. They reduce accidental swapping of IDs but need controlled construction at boundaries.
Before you start
You should be comfortable with JavaScript values, functions and objects. Use a TypeScript project with strict checking enabled when trying the examples. Separate what the compiler proves from what must still be checked when values arrive at runtime.
The practical goal is to reason through this situation: UserId and OrderId can both be strings while remaining incompatible in typed function signatures. Read the walkthrough first, then try the interview exercise before opening its answer. The important part is explaining the decision and its consequences, rather than remembering a definition alone.
Step-by-step walkthrough
Step 1: Separate domain identities
User IDs and order IDs may share string representation but represent different entities. Distinct types prevent accidental parameter swaps internally.
Step 2: Centralize construction
Validate the external string in a constructor before asserting the brand. Keep unchecked casting out of ordinary application code.
Step 3: Keep authorization independent
A valid branded ID does not prove the caller owns the record. Apply authorization when the operation is performed.
Worked scenario
UserId and OrderId can both be strings while remaining incompatible in typed function signatures.
declare const userBrand: unique symbol;
type UserId = string & { readonly [userBrand]: true };
function userId(value: string): UserId {
if (!/^u_[0-9]+$/.test(value)) throw new Error('Invalid user ID');
return value as UserId;
}
const id = userId('u_12');The constructor establishes this example’s formatting rule; the brand records that distinction for typed consumers. The string has no magical runtime marker, and an unchecked cast could forge it.
Common mistake
An assertion can forge a brand, so branding is not authentication.
Verify the behavior
Test accepted and rejected formats, then add an OrderId type and verify a swapped call fails compilation. Test record ownership separately at the server boundary.
Interview exercise
Construct a branded ID safely.
Answer and reasoning
Validate the external string in a dedicated constructor, then apply the brand and keep unchecked casts localized.
Continue learning
Compare the scenario with the TypeScript interview questions and test your understanding with the TypeScript MCQs. For terminology and implementation details, consult the reference material.