My code tracks objects with unique IDs like ProductId, CompanyId, PersonId. These share the same implementation but I want distinct types so I don’t mix them up. I also want to be able to work with these types from TypeScript. A simple approach is like the code below. But I don’t like having to pattern match each kind of ID before working with it and the constructors are a bit ugly. My question is whether it is possible to accomplish this same thing using include or functors. I tried (see code that follows) and although it works from ReScript I can NOT get it to work from TypeScript; no .gen.js file is built.
module UniqueId = {
type t = string
@genType
let makeRandom = () => "some random id"
@genType
let asText = s => s
}
module PersonId = {
@genType
type t = PersonId(UniqueId.t)
}
module CompanyId = {
@genType
type t = CompanyId(UniqueId.t)
}
let bob = PersonId.PersonId(UniqueId.makeRandom())
let bobText = switch bob {
| PersonId(id) => id->UniqueId.asText
}
Here is what I’m trying to achieve. Notice how much cleaner the code is to construct and work with ID values. But the @gentype annotations are not working as I had hoped. Nothing ends up in the .gen file.
module Make = (
P: {
let prefix: string
},
) => {
@genType
type t = string
@genType
let makeRandom = () => P.prefix ++ "some random id"
@genType
let asText = u => u
}
module PersonId = {
include Make({
let prefix = "p_"
})
}
module CompanyId = Make({
let prefix = "c_"
})
let bob = PersonId.makeRandom()
let bobText = bob->PersonId.asText
Haven’t looked at the other solution. I need to spend more time looking at it and see how it differs from what I attempted. I learned yesterday that gentype does not understand the module language, which seems like it could be a big limitation, and so I don’t yet understand what works and what does not. Will try to get my head around this all this morning.