I am developing a library with ReScript that is usually consumed by apps written in ReScript (mostly my own :)), but also bundles a JS file that can be included in pure JS environments to create, process and transform custom data structures.
Exports and bundling have been pretty easy to setup, but I am unsure how to deal with the JS consumption of the library. Since there are no typechecks in JS land, calling my functions with JS data becomes very unsafe. There was not much need for input validation or error handling in ReScript as the types already made sure no incorrect data can enter.
I am considering two options now:
- a) create a JS interop module (in ReScript) where I expose all functions I want to export to the JS bundle and wrap them around validators that check if the data actually has the correct shape or otherwise throw exceptions at the user.
- b) leave everything as is and just add some more accessor or “make” functions for my input types so that they can be used on the JS side whenever I need them to feed into a function.
Option (a) seems kind of wrong to me since the whole point of using ReScript is to have a strong type system that actually prevents invalid input in the first place, but now I have to pretend that ReScript doesn’t do its job and types never existed.
Option (b) is more appealing to me, but having to look up a specific function or variable just to get a simple boolean or numeric input for a function also seems very tedious and hard to explain to JS users who have never touched ReScript before. Of course, there would be nothing stopping them from using any kind of compatible input that may be accepted by the function even though it is actually invalid, but I think I could live with that.
Is there a “proper” way of providing an interface to JS users from a ReScript lib that they can consume safely? Maybe there is something fundamental I am missing, since this is my first compile-to-JS project.