feat: add Set and Map support to ? placeholder expansion#27
Conversation
Extend the `?` placeholder handling so that `Set` instances are expanded like arrays and `Map` instances are expanded like plain objects. - `Set` values used inside `IN (?)` or `SELECT ?` are expanded as a comma-separated list of escaped values, matching existing Array behavior. - `Map` values used in `UPDATE ... SET ?` are expanded as `` `key` = value `` pairs, matching existing Object behavior. - A `Map` used in a regular `?` position (non-SET) falls back to the default string coercion (`'[object Map]'`), consistent with how non-plain objects are handled today. - Empty `Set` and empty `Map` produce empty expansions, mirroring the behavior of empty arrays and empty objects. Tests covering each of these cases are included.
|
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #27 +/- ##
=========================================
Coverage 100.00% 100.00%
=========================================
Files 1 1
Lines 401 414 +13
=========================================
+ Hits 401 414 +13 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
|
Thanks, @mdierolf!
Since the implementation doesn't affect those who don't use these types/instances, besides the performance remaining the same, it's fine by me. @sidorares, what do you think? Note To fix the lint, you can run the command |
? placeholder expansion
Summary
This PR adds first-class support for
SetandMapto the?placeholder expansion in
format().Previously, passing a
SetorMapas a parameter fell back to thedefault object coercion, producing output like
'[object Set]'or'[object Map]', which forced callers to convert these structures toarrays/objects manually before formatting.
With this change:
Setis treated like anArray— useful forIN (?)clausesand any other list context.
Mapis treated like a plain object inUPDATE ... SET ?context — useful when the column set is built dynamically and
insertion order / non-string-safe keys matter.
Behavior
new Set([1, 2, 3])IN (?)IN (1, 2, 3)new Set([42])SELECT ?SELECT 42new Map([['name','foo'],['count',7]])UPDATE t SET ?UPDATE t SET `name` = 'foo', `count` = 7new Map([['x', 1]])WHERE data = ?WHERE data = '[object Map]'(unchanged fallback)new Set()IN (?)IN ()new Map()UPDATE t SET ?UPDATE t SETMotivation
SetandMapare increasingly common in modern TypeScript codebases(deduped IDs, ordered key/value config, etc.). Requiring callers to
Array.from(set)orObject.fromEntries(map)at every call site isboilerplate and error-prone.
These types also have the additional benefit of requiring explicit creation, as opposed to array or object types, which may be received unexpectedly when user input is not properly sanitized.
Notes / Compatibility
objects, and primitives are unchanged.
Mapfallback in non-SET positions intentionally preserves thecurrent
'[object Map]'behaviorTests
Added a new
describeblock covering:SetinIN (?)with numbers and stringsSetinSELECT ?SetinUPDATE ... SET ?(list expansion)MapinUPDATE ... SET ?(key/value expansion)Mapin a regular?position (fallback)Setand emptyMapChecklist