Immutable to Mutable Record type

Is there a way to convert a record type to mutable or read only without having to type it all again? Kind of like ReadOnly in TS, or the opposite way.

module Person = {
  type t = {name: string, age: int}
  type mut = {mutable name: string, mutable age: int}

  module Automerge = {
    type doc = Automerge.Document.t<t, mut>
  }
}

For context, I’m experimenting with some typed automerge binds.

Alternatively, is there some way to ensure the records are the same or compatible? Can a mutable record be cast with :> to the immutable version or something like that?

1 Like

Seems like :> works on record coercion and has a nice error message showing the incompatible types. See this example.

Given that, I can have a sentinel in the module like so:

    let _keepRecordsInSync = (r: t) => ((r :> mut) :> t)

Ensuring that t and mut stay in sync. Far from ideal but at least as the types grow the compiler will complain if they get out of sync when adding fields. Playground

module Person = {
  type t = {name: string, age: int, newField: string}
  type mut = {mutable name: string, mutable age: int}

  module Automerge = {
    type doc = Automerge.Document.t<t, mut>
    let _keepRecordsInSync = (r: t) => ((r :> mut) :> t)
  }
}

Gives me:

[E] Line 24, column 41:
Type mut is not a subtype of t 

  The record mut cannot be coerced to the record t because:
  - The field newField is missing in record t, but present in record mut
2 Likes