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