Gen Type Does Not Work With imported function from Typescript

When importing a function from typescript to rescript and then exporting a new
one from rescript to typescript (which uses the imported one from typescript internally) it throws the following error, (example to reproduce error is attached). By the way, I am using commonjs in package.json and bsconfig.json because I target nodejs not the browser.


  return MainGen.add(MainGen.add(a, b), c);
TypeError: MainGen.add is not a function
    at add3 (/home/user/sandbox/rescript/app/src/
    at Object._3 (/home/user/sandbox/rescript/app/node_modules/rescript/lib/js/curry.js:131:12)
    at Object.add3 (/home/user/sandbox/rescript/app/src/Main.gen.ts:20:24)
    at Object.<anonymous> (/home/user/sandbox/rescript/app/src/index.ts:9:13)
    at Module._compile (node:internal/modules/cjs/loader:1101:14)
    at Module.m._compile (/home/user/sandbox/rescript/app/node_modules/ts-node/src/index.ts:1310:23)
    at Module._extensions..js (node:internal/modules/cjs/loader:1153:10)
    at Object.require.extensions.<computed> [as .ts] (/home/user/sandbox/rescript/app/node_modules/ts-node/src/index.ts:1313:12)
    at Module.load (node:internal/modules/cjs/loader:981:32)
    at Function.Module._load (node:internal/modules/cjs/loader:822:12)
import { add3 } from "./Main.gen";

export function add(a: number, b: number): number {
  return a + b;

console.log(add3(10, 40, 1));

external add: (int, int) => int = "add"

let add3 = (a: int, b: int, c: int) => {
  add(add(a, b), c)
// Generated by ReScript, PLEASE EDIT WITH CARE
'use strict';

var MainGen = require("./Main.gen");

function add(prim0, prim1) {
  return MainGen.add(prim0, prim1);

function add3(a, b, c) {
  return MainGen.add(MainGen.add(a, b), c);

exports.add = add;
exports.add3 = add3;
/* ./Main.gen Not a pure module */
/* TypeScript file generated from Main.res by genType. */
/* eslint-disable import/first */

import {add as addNotChecked} from './index';

// @ts-ignore: Implicit any on import
const Curry = require('rescript/lib/js/curry.js');

// In case of type error, check the type of 'add' in '' and './index'.
export const addTypeChecked: (_1:number, _2:number) => number = addNotChecked;

// Export 'add' early to allow circular import from the '.bs.js' file.
export const add: unknown = addTypeChecked as (_1:number, _2:number) => number;

// tslint:disable-next-line:no-var-requires
const MainBS = require('./');

export const add3: (a:number, b:number, c:number) => number = function (Arg1: any, Arg2: any, Arg3: any) {
  const result = Curry._3(MainBS.add3, Arg1, Arg2, Arg3);
  return result

I noted that when we reassign a function to another variable then for some reason we can not call the other one as function :frowning: . What I mean is doing the following:

function A() => "Hello";
// calling A() at this point and any other point works as expected
const B = A;
// calling B() throws the same error -> (B  is not a function)
const C = B;
// calling C() throws the same error -> (C  is not a function)

this something similar to the code that Gen Type generates

I found that the issue is having cyclic dependencies. It takes some time for nodejs to resolve them before values can actually be used. Therefore, when developing for commonjs one must avoid cyclic dependencies between rescript files and typescript files (at the end this compiles to cyclic dependency between .ts files).

Note: genType by default creates cyclic dependencies between .gen.ts files and bs.js files, this does not cause an issue though.

For Reference: javascript - Import from index.ts returns undefined - Stack Overflow