Allow using `...` operator to shallow copy a record without rewrite any fields

type state = {
  id: string,
  frames: array<Js.TypedArray2.Uint8Array.t>,
  duration: float,
  width: int,
  height: int,
}

type mutableState = {
  mutable id: string,
  mutable frames: array<Js.TypedArray2.Uint8Array.t>,
  mutable duration: float,
  mutable width: int,
  mutable height: int,
}

let state: state = {
  id: "1",
  frames: [Js.TypedArray2.Uint8Array.fromLength(100)],
  duration: 10.,
  width: 100,
  height: 100
}

let mutableState: mutableState = {
  ...(state :> mutableState),
  id: "2" // must has a field
}

let mutableState: mutableState = {
  ...(state :> mutableState),
}

playground here

Currently, just only use ... to shallow copy a record is not allowed, you must rewrite some fields at the end of the new record. But the need for shallow copying a record by using ... in ts/js is very normal and useful, i think we can add this into Rescript!

1 Like

I’d argue that it’s not very normal or useful. If you use immutable patterns throughout your code, you don’t need it at all, so all you achieve by rest spreading is unnecessary GPU/memory load (including unnecessary rerenders/effects firing in React).

If you have to copy due to interop with some code that mutates your records, you can always bind to Object.assign. Sure, it’s more of an eyesore, but I suppose places like this should stick out.

2 Likes

I like the current behavior and this warning. It helps avoid doing something that isn’t needed that has an impact on performance.