ECMAScript As-Patterns for Matching and Destructuring


Stage: 0

Author: Kat Marchán (npm, @maybekatz)

Champions: Kat Marchán (npm, @maybekatz)


When matching non-Identifier values, it's often the case that users might want to also bind that value to an Identifier while doing the matching. For this reason, it's proposed that destructuring be extended with the ability to do this sort of binding. Furthermore, the separate pattern matching proposal will benefit from this change by allowing matching operations against values that are also put into identifiers, since identifiers are irrefutable patterns.

The syntax uses an as keyword, and looks as follows:

const {x: {y} as x} = {x: {y: 1}}
// x is {y: 1}
// y is 1


function foo ([{y} as x, [z] as zed = [1]]) {
  // x is {y: ...}
  // y is x.y
  // z is runs an initializer if arguments[0][1] is undefined

This applies similarly to match:

match (x) {
  when {x: {y: 1} as x} ~> console.log(x.y === 1)

Note: This syntax is used by F#. It's also reminiscent of as syntax in import statements, so there's some precedent in the language for this sort of binding (import * as bar from './x.js')

The Big Picture



12.15.5 Destructuring Assignment Changes:

AssignmentRebinding :
  `as` IdentifierReference

AssignmentElement :
  DestructuringAssignmentTarget AssignmentRebinding
  DestructuringAssignmentTarget Initializer
  DestructuringAssignmentTarget AssignmentRebinding Initializer

13.3.3 Destructuring Binding Patterns Changes:

BindingRebinding :
  `as` IdentifierReference

BindingElement :
  BindingPattern BindingRebinding
  BindingPattern Initializer
  BindingPattern BindingRebinding Initializer

Match Operator Syntax Changes:

MatchRebinding :
  `as` IdentifierReference

MatchElement :
  MatchPattern MatchRebinding
  MatchPattern Initializer
  MatchPattern MatchRebinding Initializer