I am assuming it might be easier to sacrifice type safety of these arguments for a simpler implementation, but I am unsure how to get ReScript to generate these objects.
How would I start modelling an external function like this one?
MongoDB is highly dynamic… i don’t think you will be very happy manually encoding / decoding all the results every time you need to do another request to the database.
Probably just better to type the query parameter as a generic Js.t object instead, or in case you want to have some static analysis, abstract commonly used queries into factory functions and hide the Query.t in an abstract type.
// Query.res
type t = Js.t({.}); // You can hide the concrete impl of t with a Query.resi file as well
let status = (status: string) => {
{ "status": status }
}
For your type issue reagarding array with multiple values of different types, might be worth having a look at an old blog post about expressing “union types” in ReScript. It’s not the most elegant thing, because it’s using some pretty advanced type system features, and usually I’d recommend not trying to use arrays that mix different value types.
Note that this example wouldn’t work in an array, as in the the example. The reason for that is that when you structurally type it to an object with a status field, an object with a qty field will not be possible in the array (because it’s not the same type). A solution is to make an opaque type and use the following to convert:
type status;
external toStatus: 'a => status = "%identity";
let status1 = {"status": "A"}->toStatus;
let status2 = {"qty": {"lt": 30}}->toStatus;
// array syntax for the experimental syntax is just []
let arr = [|status1, status2|];
Looks great. People sometimes are obsessed with 0-cost bindings. It really doesn’t make a difference for 99% of the bindings, so if the binding can be nicer with some runtime overhead it’s usually ok! Especially in this case if it’s a binding to a database, these things are not called in a tight loop, and the call itself results in io, so not CPU limited.