this is a breaking change which we'd previously talked about trying out, and now it has landed!
the change is pretty simple: previously, if we did this...
{ x, y } = { x: 1, y: 2, z: 3 }
...it worked without any compiler warnings or anything like that, even though not all the fields were used.
in Rust, you'd get a compiler warning unless you did one of these instead:
{ x, y, z: _ } = { x: 1, y: 2, z: 3 }
{ x, y, .. } = { x: 1, y: 2, z: 3 }
the tradeoff between these is:
_ or ....) and now if you ever add another field to that record, the compiler will tell you about all the places where you used this technique and haven't updated to use the new field yet.I think that last point is particularly interesting. I remember back in my Java days when writing custom "equals" and "hash code" methods, it was a footgun that you could add a new field and forget to incorporate it into your equals/hashing operations, and then they would just silently be broken :sweat_smile:
this is a way to prevent that from happening: inside your custom equals/hashing function, you destructure all the record fields on purpose, so that if you ever add another one, you get a compiler warning saying it's unused, which reminds you to incorporate them into those functions
anyway, even though it's more verbose than the first case, I think the benefits the .. design unlocks are worth trying out - so now we have that design too!
can you bind to .. as well? it would be neat if you did { x, y, ..rest } = { x: 1, y: 2, z: 3 }, and could get rest == { z: 3 }.
I think this would Just Work, due to how record extensibility works. it's kinda like type narrowing! or phrased differently, stripping fields off of a record
ha, that's a cool idea! It hadn't occurred to me, but I agree we should do that :+1:
it would be neat if you did
{ x, y, ..rest } = { x: 1, y: 2, z: 3 }, and could getrest == { z: 3 }.
A pattern I've used a lot in JS/TS, for what it's worth.
Last updated: Jul 23 2026 at 13:15 UTC