Name your booleans at the call site
A function call like sendEmail(user, true, false, true) forces the next developer to read the signature before understanding what each argument does. Name the booleans instead.
A function call like `sendEmail(user, true, false, true)` is a readability tax paid on every read, every review, every debugging session. The first time you write it you know which boolean means what. A month later — or during a code review 30 seconds after the PR is opened — everyone has to jump to the function signature or the editor's type hint to decode positional booleans.
The fix is straightforward: use a destructured options object. `sendEmail(user, { includeAttachments: true, ccAdmin: false, trackDelivery: true })` is self-documenting. TypeScript gives you autocomplete and type-checking for free. The only cost is a few extra characters at the call site, and the payoff is measured in every future interaction with that line of code.
There is a secondary benefit: when the function needs a new option later, adding a property to the options object is backward-compatible. Adding a new positional parameter requires touching every call site. In a growing codebase, that difference compounds rapidly.