Symptom

Domain concepts represented as raw strings, numbers, or booleans — phone number is a string, money is a number, status is a code.

Goal

Each domain concept has a small typed home — Money, PhoneNumber, OrderId, Status — that knows its rules.

Smellier version

function priceFor(cents, currency) {
// ...
}

Fresher version

class Money { /* amount + currency, with arithmetic */ }
function priceFor(money) {
// ...
}
Example source: Illustrative example written for this site, not a quotation from any source.
Pressure

Validation and formatting scatter across every consumer; the type system can't catch wrong primitives in the wrong slot.

Tradeoff

Each wrapper class adds construction ceremony at every entry point; for one-off primitives that never carry domain rules, the wrapper is overhead with no return.

Relief

Misuse becomes a type error; behavior accretes around the concept; refactoring is local to the wrapper.

Trap

Wrapping every primitive on principle — Name, Title, Description as separate classes whose only methods are toString() — adds typing ceremony without enforcing any domain rule.