Union type for specific javascript bindings


#1

I have a specific case, where I want to bind javascript API (nodejs) environment, to Reason.

The object is as follows:

type ctx = {.
    [@bs.set] "body": string,
    "request": request,
    "response": response
  };

Here, as a standard, body might be several things:

string written
Buffer written
Stream piped
Object || Array json-stringified
null no content response

In typescript and flow you can produce such union easily, but in reasonML, this is obviously not possible:

type ctxBody = string | Js.t('a)

How does one achieve that?


#2

I think you need a variant type with constructor arguments.

type ctxBody =
  | NativeString(string)
  | JsT(Js.t)
  ;

And the switch:

let s =
  switch(body) {
  | NativeString(ns) => ns
  | JsT(obj) => parseBodyObj(obj)
  }

#3

I would suggest the Bucklescript cookbook :slight_smile:


#4

I didn’t get too far with the cookbook examples, but here’s the answer how to do it:

Since Reason is missing untagged unions it is rather problematic.


#5

That’s exactly what described in the cookbook. And the answer is written by the same person


#6

Not entirely, the example there is about Json, if someone knows that you can classify default JS types like this then probably. SO answer is just a better example for described general case string | number.

This is a very common thing to do in TS or Flow that it should maybe be in a documentation somewhere, rather than Cookbook (that seems to have quite outdated syntax as well).