I’m experimenting with Rescript inside a Remix project (remix.run), the web framework from the React router folks. Is there a more interesting, fun way to enforce the types for these to functions without duplicating the types? See playground link for some light code.
export let loader: LoaderFunction = () => {
return fetch("https://api.github.com/gists");
};
export default function Gists() {
let data = useLoaderData(); // returns the value of loader
aside: building up the possible ways to have generated type-safety in a rescript project from database to web framework will be my happy place to json would be my happy place. easy to setup new projects, throw away, iterate on new domains.
It’s been a while since I played with remix. But around that time, there wasn’t a good way to achieve this, and everyone seemed to build their solution to that problem (have a look at the issues around this in their repo, including my own proposal for infering the types) - the repo is private as of right now, but I think it will open up this week.
But I guess it would mainly depend on the types of the bindings that you can write for remix.
module Make = (
I: {
type t
let loader: unit => Js.Promise.t<t>
},
) => {
let loader = I.loader
@module("remix") external useLoaderData: unit => I.t = "useLoaderData"
}
type gist = {id: int}
module Gists = Make({
type t = array<gist>
// you can fetch, etc. whatever here, the compiler will make
// sure you return the right type
let loader = () => Js.Promise.resolve([{id: 1}])
})
let loader = Gists.loader
let component = () => {
let _data = Gists.useLoaderData()
}
For each page you’d make a new module specifying the page’s data type and loader function
Here’s a playground link for the above to see the types on hover and JS output
It’s unfortunate but not all files can be in Rescript. If you’ve seen Ryan’s nextjs Rescript starter, iirc the pages are in js/ts and imports Rescript code.
I’d write the pages in typescript, but import the necessary code from Rescript. Define your loaders, actions elsewhere then import and export them wholesale from within your remix pages.
Also, I think you’re the only person publicly working on this haha. I’ve only tried a couple times.
Haha, someone has to push this stack, it’s got the best name: Rescript-React-Remix
It’s a shame, I wanted to migrate a production app this week, but the way I see it, for this to work well those two points I mentioned need to be fixed. Not sure why Rescript only supports some exotic file names And on top of that Remix needs to allow for specifying a pattern to ignore files in the routes directory, eg. ignorePath ‘**/*.res’
Bit of a late reply but I think both of these should be solvable if we are willing to accept alternatives.
We can use the routes config instead of specially named files.
Get remix to ignore the .res files? I get an error: “Invalid route module file: …/index.res”
We can set "in-source": false in the ReScript config file and point the Remix compiler at the lib/ directory where the generated JavaScript files are output to.