Tagged Collection Literals ?
- Stage: Unstaged
- Status: Withdrawn
- ECMAScript edition: —
- Synchronized: Aug 28, 2026
- 中文译文 · Source repository
The proposal introduces tagged collection literals that allow custom constructors to be used with object, array, and value literal syntax via a .from() method. It also extends destructuring and pattern matching with a Symbol.valueOf protocol, enabling custom collection types to participate in those operations. The goal is to provide concise syntax for building and matching custom data structures while preserving their individual invariants.
The README below comes from the upstream repository and may contain outdated stage or status metadata. Use the proposal details above as the current source of truth.
ECMAScript Tagged Collection Literals
Status
Stage: WITHDRAWN
Author: Kat Marchán (npm, @maybekatz)
Champions: Kat Marchán (npm, @maybekatz)
WITHDRAWN
This proposal was presented to TC39 in May 2018 and voluntarily withdrawn during
discussions. The author concluded this issue was best solved through an
object-destructuring protocol corresponding to sequence iterators, in
combination with Map.from() and company.
JavaScript, unlike a lot of the static languages pattern matching concepts were based on, does not include enough static typing information to make things like destructuring or pattern matching efficient and cacheable enough to work well in these cases and stay performant. Additionally, this additional syntax did not add enough value to be worth the syntax budget expenditure.
A different proposal will be submitted based on this one that talks about creation/extraction protocols in a unified way, but without adding additional syntax.
Introduction
This proposal extends both destructuring binding/assignment and the match
statement with the ability
to apply custom destructuring and matching operations to matched data. It also
adds a new constructor syntax for building these custom data structures with
concise object and array style syntax while preserving their individual benefits
and invariants.
The syntax itself is derived from similar syntax in multiple other languages used for this purpose, and is meant to be reminiscent of tagged template literals in JavaScript -- except using other literal syntaxes available in the language.
This proposal is derived from a previously-discussed extensible collection literals, but adds significant work as far as how this syntax interacts with destructuring and matching.
Motivating Examples
Convenient construction of object-like and array-like data structures:
Destructuring assignment/binding:
Match statement compatibility:
The Big Picture
Related Active Proposals
- Pattern matching
- Frozen/sealed object syntax
- Richer Keys
Object.fromEntries- Smart Pipelines
ofandfromconstructors
Construction Literals
For construction, literals are a thin layer of syntax sugar over
Constructor.from() functions. When a literal construction expression is found,
the left hand side is evaluated for its value, and the right hand side is
converted to an iterator or an atomic value. The type of value passed to
.from() depends on which of the three syntaxes is used:
Benefits
For Objects, the benefits are more obvious: No conversion to ToString,
parse-time early errors for invalid key/value syntax, and more appropriate
syntax for key/value types, instead of having to write nested arrays.
For Arrays and Values, the benefit on this end of things is smaller, and largely
based on convenience, with the exception that it does help ease a common footgun
with new:
While this behavior is consistent, it is something that does occasionally bite people. Literal syntax helps ease this a bit, specially in data structure-heavy code:
But, as implied before, the main benefit of extending tagged literal syntax to arrays and individual values is the correspondence to destructuring...
Destructuring Literals
When a user learns they can construct with one syntax, is becomes much easier to teach them how to destruct with it.
While the common .from() method mechanism is what makes construction literals
work, destructuring uses the standard iterator protocol through a
Symbol.valueOf constructor method. If Symbol.valueOf is not present,
.valueOf() is tried instead. If array or object-destructurng syntax is used
without RestProperty/RestElement, .valueOf() will receive an array of keys
that are being requested from the object. If an atomic destructure is requested,
the second argument to valueOf() will be undefined. Filtering entries based
on these keys is optional.
The valueOf method should return an iterator
When a destructuring sequence is used, the iterator will be used as-is to match and fill entries in the destructured array or object.
If valueOf returns undefined, the match is considered to have failed, and no
values will match. When used with match, this will cause the match clause to
fail.