Skip to content

Conditional destructure if { x } .= y enters block when y.x === undefined #2106

@STRd6

Description

@STRd6

if { x } .= y currently compiles to a key-presence test:

if (y && typeof y === 'object' && 'x' in y) {
  let { x } = y;
  ...
}

So if { x } .= { x: undefined } enters the block with x === undefined. switch y; when { x } uses the same semantics, intentionally — object pattern matching is shape-based.

In if context the key-presence test is surprising. The natural reading is "if I can pull a usable x out of y, do this," and undefined values silently passing the guard has caused at least one real bug.

Proposal

In if-form destructuring, require each bound name to be != null before entering:

if (y && typeof y === 'object' && y.x != null) {
  let { x } = y;
  ...
}

Rationale:

  • != null (not full truthiness) preserves 0/""/false as legitimate values — same tradeoff if x := y already makes for the single-name case.
  • Matches the intuitive read of "extract these values, only if they're set."

Open questions

  1. Apply only to if-form, or also to switch when { x }? Diverging keeps switch as pure shape-match; aligning keeps the two siblings consistent.
  2. Breaking change for any code relying on the current key-presence-with-undefined behavior — likely rare but worth scanning the codebase.
  3. Nested patterns (if { a: { b } } .= y) — recurse the check, or only top-level?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions