Shim alternative for genType RescriptCore types

I’ve got a simple button component but the .tsx generated includes this import that doesn’t exist:

import type {Jsx_element as PervasivesU_Jsx_element} from './PervasivesU.gen';

I’m seeing this a lot on each @react.component that I’m using @genType on. I’m assuming that there’s something obvious that I’m doing wrong here.

Here’s this specific component’s src

type variant = [#Button(ReactEvent.Mouse.t => unit) | #A(string)]

type size = [#sm | #md | #lg]

type shape = [#oval | #circle]

type color = [#smoke | #lime]

@genType @react.component
let make = (
  ~variant: variant,
  ~isActive=false,
  ~icon: option<React.element>=?,
  ~size=#sm,
  ~className="",
  ~children: React.element,
  ~shape=#oval,
  ~color=#smoke,
  ~ref_: option<ReactDOM.domRef>=?,
): React.element => {
  let shapeBaseClass = "rounded-[90px] px-4"

  let shapeClass = switch shape {
  | #oval => shapeBaseClass
  | #circle => `${shapeBaseClass} rounded-full px-2.5`
  }

  let colorBaseClass = `border-phantom bg-black hover:bg-phantom active:bg-phantom ${isActive
      ? "text-smoke"
      : "text-graphite hover:text-space"}`

  let colorClass = switch color {
  | #smoke => colorBaseClass
  | #lime =>
    `border-transparent text-brand-green hover:bg-lime-20 hover:border-lime-20 active:bg-lime-20 ${isActive
        ? "bg-lime-20"
        : "bg-lime-10"}`
  }

  let labelBaseClass = icon->Option.map(_ => "")->Option.getOr("w-full")

  let labelClass = switch size {
  | #sm => `${labelBaseClass} text-body-sm leading-body-sm`
  | #md => `${labelBaseClass} text-body-md leading-body-md`
  | #lg => `${labelBaseClass} text-body-lg leading-body-lg`
  }

  let sizeClass = switch size {
  | #sm => "gap-1"
  | #md
  | #lg => "gap-2"
  }

  let combinedClass = `g-focus flex flex-nowrap items-center py-1.5 border transition-all ${shapeClass} ${colorClass} ${sizeClass} ${className}`

  switch variant {
  | #Button(onClick) =>
    <button ref=?{ref_} className=combinedClass onClick={onClick}>
      <span className={labelClass}> {children} </span>
      {icon->Option.getOr(React.null)}
    </button>
  | #A(href) =>
    <a ref=?{ref_} className=combinedClass href>
      <span className={labelClass}> {children} </span>
      {icon->Option.getOr(React.null)}
    </a>
  }
}

I realize now that previously to resolve this we would use shims (it’s been a while). But seeing as how those are deprecated now (TypeScript | ReScript Language Manual) is there a suggested alternative?

There’s quite some work happening in the background to change how genType works, to remove any runtime from it, but in the meantime I think you’ll still have to use shims. It’s just weird that it expects this Jsx_element, especially since you don’t seem to use this type in your code base. Maybe you should open an issue in the repo. What’s the JSX config and the version of rescript you use?

Thanks for taking the time to respond. It looks like per the docs linked above shims have been deprecated and no longer work.

I’m using 11.1 and here’s my config:

{
  "name": "app",
  "sources": [
    {
      "dir": "src",
      "subdirs": true
    },
    {
      "dir": "packages",
      "subdirs": true
    }
  ],
  "package-specs": [
    {
      "module": "esmodule",
      "in-source": true
    }
  ],
  "reanalyze": {
    "suppress": ["src/bindings", "src/common/pages"]
  },
  "suffix": ".js",
  "jsx": { "version": 4 },
  "bs-dependencies": ["@rescript/core", "@rescript/react"],
  "bsc-flags": ["-open RescriptCore", "-open Global"],
  "gentypeconfig": {
    "module": "esnext",
    "moduleResolution": "bundler",
    "generatedFileExtension": ".gen.tsx"
  }
}

This could definitely a bug, the best would be to come up with a simple repro repo and open an issue. Given how widespread is the use of react for rescript users, it’s weird you’re the only one complaining about it, it’d be good if other genType users could chime in.

I just tested this out in project using the latest versions of rescript and rescript-react and I wasn’t able to reproduce.

Here’s the output I have from the button component you shared:

/* TypeScript file generated from btn.res by genType. */

/* eslint-disable */
/* tslint:disable */

import * as React from 'react';

import * as btnJS from './btn.js';

export type variant = 
    { NAME: "Button"; VAL: (_1:MouseEvent) => void }
  | { NAME: "A"; VAL: string };

export type Props = {
  readonly children: React.ReactNode; 
  readonly className?: string; 
  readonly color?: 
    "lime"
  | "smoke"; 
  readonly icon?: JSX.Element; 
  readonly isActive?: boolean; 
  readonly ref_?: React.Ref<unknown>; 
  readonly shape?: 
    "circle"
  | "oval"; 
  readonly size?: 
    "lg"
  | "md"
  | "sm"; 
  readonly variant: variant
};

export const make: React.ComponentType<{
  readonly children: React.ReactNode; 
  readonly className?: string; 
  readonly color?: 
    "lime"
  | "smoke"; 
  readonly icon?: JSX.Element; 
  readonly isActive?: boolean; 
  readonly ref_?: React.Ref<unknown>; 
  readonly shape?: 
    "circle"
  | "oval"; 
  readonly size?: 
    "lg"
  | "md"
  | "sm"; 
  readonly variant: variant
}> = btnJS.make as any;

Maybe try npx rescript clean?

I’ve cleaned multiple times. The issue is when using genType on types that require ReScriptCore modules. I believe you couldn’t reproduce b/c your code doesn’t use any of these. I’ll fire up a repro that hopefully reproduces this in a bit.

1 Like

Here’s a new repo with the issue: GitHub - painedpineapple/gentype-rescriptcore-bug-repro

It seems clearly the output for the type requiring shims, and alternatives depend on what your needs

I can’t find anything like Jsx.element in your code, and the type name is unfamiliar to me, so I assume this has something to do with the most recent changes, the generic jsx transform? cc @zth