Skip to content
Pattern matching syntax for ECMAScript
Branch: latest
Clone or download
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
CORE.md wip: write up about expression format Jun 5, 2019
README.md Fix a syntax error in the example (#142) Jun 30, 2019
TO_INFINITY_AND_BEYOND.md fix catch-match May 25, 2018

README.md

ECMAScript Pattern Matching

Status

Stage: 1

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

Champions: Brian Terlson (Microsoft, @bterlson), Sebastian Markbåge (Facebook, @sebmarkbage), Kat Marchán (npm, @maybekatz)

Introduction

This proposal adds a pattern matching expression to the language, based on the existing Destructuring Binding Patterns.

There's many proposals potentially related to this one, and other proposals might mention interaction with this. This file includes casual, example-based discussion of the proposal, and there's also a document describing the core semantics in more formal language, which will be iterated over into the final Spec-ese.

There's also a document including suggestions for other future proposals, which are dependent on this one, but do not directly affect the main behavior of the feature.

This proposal was approved for Stage 1 in the May 2018 TC39 meeting, and slides for that presentation are available.

This proposal draws heavily from corresponding features in Rust, F#, Scala, and Elixir/Erlang.

Motivating Examples

Matching fetch() responses:

const res = await fetch(jsonService)
case (res) {
  when {status: 200, headers: {'Content-Length': s}} ->
    console.log(`size is ${s}`),
  when {status: 404} ->
    console.log('JSON not found'),
  when {status} if (status >= 400) -> {
    throw new RequestError(res)
  },
}

Terser, more functional handling of Redux reducers. Compare with this same example in the Redux documentation:

function todoApp (state = initialState, action) {
  return case (action) {
    when {type: 'set-visibility-filter', filter: visFilter} ->
      ({...state, visFilter}),
    when {type: 'add-todo', text} ->
      ({...state, todos: [...state.todos, {text}]}),
    when {type: 'toggle-todo', index} -> (
      {
        ...state,
        todos: state.todos.map((todo, idx) => idx === index
          ? {...todo, done: !todo.done}
          : todo
        )
      }
    )
    when _ -> state // ignore unknown actions
  }
}

Or mixed in with JSX code for quick props handling, using the expression version:

<Fetch url={API_URL}>{
  props => case (props) {
    when {loading} -> <Loading />
    when {error} -> <Error error={error} />
    when {data} -> <Page data={data} />
  }
}
</Fetch>

(via Divjot Singh)

General structural duck-typing on an API for vector-likes.

const getLength = vector => case (vector) {
  when { x, y, z } -> Math.sqrt(x ** 2 + y ** 2 + z ** 2)
  when { x, y } -> Math.sqrt(x ** 2 + y ** 2)
  when [...etc] -> vector.length
}
getLength({x: 1, y: 2, z: 3}) // 3.74165

Implementations

You can’t perform that action at this time.