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