rescript-association / genType

Auto generation of idiomatic bindings between Reason and JavaScript: either vanilla or typed with TypeScript/FlowType.

Home Page:https://rescript-lang.org/docs/gentype/latest/introduction

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

@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.

https://forum.rescript-lang.org/t/how-to-create-distinct-uuid-types-and-access-them-from-typescript/4019

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.

https://forum.rescript-lang.org/t/how-to-create-distinct-uuid-types-and-access-them-from-typescript/4019

This is not going to help with that issue. Functors in that use are not supported at the moment.