Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

@genType not generating correct TypeScript definitions for module aliases #6112

Closed
cristianoc opened this issue Apr 6, 2023 · 5 comments
Closed

Comments

@cristianoc
Copy link
Collaborator

Description:

When using @genType with module aliases, the generated TypeScript definitions are not correctly referencing the aliased modules. This issue occurs when trying to access types and functions through the module alias.

Example:

Consider the following ReScript code:

// MyModule.res
@genType
type t = int

@genType
let add: (t, int) => int = (x, y) => x + y

// Wrapper.res
module MyModuleAlias = MyModule

// Usage.res
open Wrapper

let a = 5
@genType
let b = MyModuleAlias.add(a, 3)

Expected behavior:

The @genType annotations should generate the correct TypeScript type definitions and import paths, even when using module aliases.

Actual behavior:

The generated TypeScript definitions are not correctly referencing the aliased modules, causing issues when trying to use the aliased types and functions in a TypeScript/JavaScript context.

For more discussion see: rescript-lang/rescript-core#128

@jmagaram
Copy link
Contributor

jmagaram commented Apr 8, 2023

This might be related...

module Doubled = (
  C: {
    let original: int
  },
) => {
  @genType
  let doubled =
    C.original + C.original
}

// Nothing in `.gen.tsx` file
module X = Doubled({
  let original = 8
})

// Works - a `.gen.tsx` file generated
module Y: {
  @genType
  let doubled: int
} = Doubled({
  let original = 4
})

cristianoc added a commit that referenced this issue Apr 9, 2023
@jmagaram
Copy link
Contributor

jmagaram commented Apr 9, 2023

Amazing. I want to try this. What version is this in? Not sure how to get it using my package.json settings.

@fhammerschmidt
Copy link
Member

fhammerschmidt commented Apr 9, 2023

@jmagaram You can go to any successful GitHub action run like this one: https://github.com/rescript-lang/rescript-compiler/actions/runs/4649563108 and download the npm-packages artifact.
Then unpack the folder and move the rescript tgz into your repository and install it with your package manager.

e.g.
npm install ./rescript-11.0.0-alpha.1-9c378e8.tgz

@jmagaram
Copy link
Contributor

This seems to work pretty well EXCEPT for the last case below which may or may not be related to this. I'll open a separate issue.

EXPERIMENT 1

In my repro example I added @genType to the module in the Special wrapper like this...

@genType
module ArrayIndex = Special__ArrayIndex

...and then when I try to use Special.ArrayIndex.t somewhere else, like this, the TypeScript files look good. It works!

@genType
type goop1 = {x: Special.ArrayIndex.t}

One thing that is interesting and useful is that when I apply @genType to the module alias it exports EVERYTHING in the module to TypeScript, not just those items in the module that have annotations on them. I think this is very intuitive. I'm saying "generate typescript for this whole module" and that is what it is doing.

EXPERIMENT 2

When I put the annotation on the result of the functor it takes everything in that module and exports it.

module Doubled = (
  C: {
    let original: int
  },
) => {
  let doubled = C.original + C.original
  let tripled = C.original * 3
}

@genType
module X = Doubled({
  let original = 8
})

EXPERIMENT 3

It works just for regular modules like this...

@genType
module Z = {
  let x = 3
  let y = 7
}

EXPERIMENT 4

I tried to see what happens if there are annotation inside the module. This exports everything in the module and does the special renaming on the type t.

@genType
module T: {
  @genType.as("wow")
  type t
  let x: int
} = {
  type t = string
  let x = 3
}

EXPERIMENT 5

I'm looking at @genType.ignoreInterface and external functions.

module type ZipType = {
  @genType.ignoreInterface
  let realValue: string => float
}

// Nothing generated for this import statement so you can't use it
module Zip: ZipType = {
  @genType.import("./MyMath")
  external realValue: string => float = "zipfunction"
}

// This works
module Banana = {
  @genType.import("./MyMath")
  external realValue: string => float = "bananafunction"
}

@jmagaram
Copy link
Contributor

Experiment 6

This doesn't work. Nothing gets generated. If I put @genType on all the modules it works. I started writing some docs for the web site saying that modules are now supported, but I'm not sure exactly what to say. Do you think I should write those docs? Should it say "You can put the annotation on a module and EVERYTHING inside that can be exported will be exported, regardless of whether items inside have the annotation. However, every module must have the annotation to be included?" Not sure how to explain the limitations.

module Utilities__Math = {
  type point = {x: float, y: float}
  let add = (x, y) => x + y
  let multiply = (x, y) => x * y
}

module Utilities__Text = {
  type word = string
  let combine = (a: word, b: word) => a ++ b
}

@genType
module Utilities = {
  @genType
  module Math = Utilities__Math
  @genType
  module Text = Utilities__Text
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants