@gentype annotation is required for .gen.tsx creation; using functors not sufficient
jmagaram opened this issue · comments
Consider this file. GenType creates everything I expect, including a constant for the whole NegativeInt
module. BUT comment out the @genType let bozo = 0
and NOTHING gets generated. This seems really odd. Why would the inclusion of the bozo
line affect generation of anything else?
Separately, I'm finding some inconsistent behavior with trying to generate those wrapped up constant exports like NegativeInt
that include all the defined module functions. Sometimes it creates the constant with everything wrapped up, and sometimes it only creates the pieces inside NegativeInt
without a wrapper. Can't pin this down. I was actually surprised it ever works since you can't put a genType annotation on the module itself and I thought it only worked with first class modules.
module type Validated = {
type t
type domain
@genType
let make: domain => option<t>
@genType
let makeExn: domain => t
@genType
let value: t => domain
}
module type Config = {
type domain
let validate: domain => option<domain>
}
module type MakeValidated = (P: Config) => (Validated with type domain := P.domain)
module Make: MakeValidated = (P: Config) => {
type t = P.domain
let make = v => v->P.validate
let makeExn = v => v->make->Option.getExn
external value: t => P.domain = "%identity"
}
module NegativeInt = Make({
type domain = int
let validate = n =>
switch n < 0 {
| true => Some(n)
| false => None
}
})
// Comment out these lines and nothing is generated
@genType
let bozo = 0
Part of what gets generated...
export const NegativeInt: {
makeExn: (_1: number) => NegativeInt_t;
value: (_1: NegativeInt_t) => number;
make: (_1: number) => null | undefined | NegativeInt_t;
} = ExperimentBS.NegativeInt;
I ran into this problem again and have a simpler scenario that is easier to explain. My app is tracking various objects with unique identifiers like a PersonId, CompanyId, ProductId, etc. These all use the same implementation, a javascript uuid library. Even though PersonId, CompanyId, etc. use the same implementation I want a different type for each so my code doesn't inadvertently mix them up. I want to be able to access these types in TypeScript so I'm using GenType. The problem is that GenType won't reliably generate a .gen.tsx
for me.
Here is UniqueId.res
...
module type T = {
type t
@genType
let makeRandom: unit => t
@genType
let value: t => string
}
module type MakeType = () => T
module Make: MakeType = () => {
type t = string
let makeRandom = () => Js.Math.random()->Float.toString
let value = i => i
}
Here I use it in PersonId.res
...
include UniqueId.Make()
@genType
let _ignore = 0
The problem/bug is that if I do NOT include that let _ignore=0
line, NO .gen.tsx
file is generated.
Another way to handle all this is for me to not use functors and instead to have a single type UniqueId.t. And then wrap it. For example, my PersonId.res
could have code like type t = PersonId(UniqueId.t)
and my CompanyId.res
could have type t = CompanyId(UniqueId.t)
. But I think this create a lot of extra work when using these types because I need to always unwrap them.
The GenType repo has moved into the compiler. This change should handle your case: rescript-lang/rescript-compiler#5903
Though compiler v11 will not be releases for some time.
I'd really appreciate it if you could tell me whether the fix for this bug would address the issue described below. Basically when I use functors the @gentype
annotations don't get carried forward and used where the new type is built.
I'd really appreciate it if you could tell me whether the fix for this bug would address the issue described below. Basically when I use functors the
@gentype
annotations don't get carried forward and used where the new type is built.
This is not going to help with that issue. Functors in that use are not supported at the moment.