Intercepting sets on array-like objects

Tab Atkins Jr. jackalmage at
Thu Jun 8 18:32:50 UTC 2017

Heya!  As part of designing the CSS Typed OM
<>, we've ended up with at
three (so far) places where we want an interface that represents a
list of values:

* CSSUnparsedValue
representing alternating unparsed strings and variable references in a
* CSSNumericArray
representing the n-ary arguments of sum/product/min/max operations
* CSSTransformValue
representing a list of transform functions

The most natural way to represent these is as an Array, so authors can
get all the Array methods, use `val[i]` syntax, etc.  However, doing
so means we lose the ability to type-check sets to the values.

In general, type-checking is an important part of APIs defined in
WebIDL.  Any set to a property on an object is automatically
type-checked, any arguments to methods are automatically type-checked,
etc.  By building this into WebIDL, it removes the need for a lot of
annoying boilerplate on the part of spec authors, and more
importantly, removes the possibility that spec authors will forget to
typecheck at all, or will typecheck in incorrect or weird bespoke
ways.  Every API responds in exactly the same way when you pass the
wrong type of object, and that's a Good Thing for both users and

And so, it would be great to have the same ability to typecheck these
Array-likes in the Typed OM.

Naively, this requires a Proxy, so we can intercept uses of the []
syntax.  However, we don't need all the rest of the Proxy
functionality, just this one intercept - a setter function, just for
`obj[foo]` rather than ``.  Further, Typed Arrays already have
*precisely* the functionality I'd like to use - they intercept setting
using [], and convert it into the appropriate type of number.  AWB
also proposed adding exactly this hook in the past (I think it was
called "Array reformation" or something?).


Note that if we don't get some variant of this functionality, these
APIs will instead do one of:

* just using Proxies (already defined in WebIDL)
* using .get()/.set() functions with integer arguments to badly emulate arrays
* just relying on iterator/constructor, so users have to convert the
object to an Array, fiddle with it, then construct a brand new object

And whichever I end up with, I'll be advocating that as the Standard
WebIDL Way to do array-likes, so we can finally have some consistency.


More information about the es-discuss mailing list