Using unsafe [@bs.deriving jsConverter] variants with switch case

interop

#1

I am trying to use new [@bs.deriving abstract] features. I can compile code but in runtime it works not as expected. I am not sure I use them 100% correctly, but code compiles and in runtime I get absolutely different types.

ReasonML Playground does not support jsConverter, so I provide listings.

Say, I have such types:

[@bs.deriving jsConverter]
type tFilterOperation = [ | `OR | `IN | `NOTIN];

module Filters = {
  [@bs.deriving abstract]
  type oldFilter = {operation: tFilterOperation};
  external jsonToOldFilter : Js.Json.t => oldFilter = "%identity";
};

And I have such function which works with Js.Json.t input and prints different Js.Logs based in variants:

let requestOldFilters = (oldFilterJson: Js.Json.t) => {
 /* operation in RUNTIME is 'oldFIlterJson.operation' and is a STRING */
  let operation =
    oldFilterJson
    |. Filters.jsonToOldFilter /* convert to ReasonML type */
    |. Filters.operation; /* use auto generated accessor function to get value */
  switch (operation) { /* here ReasonML thinks, that operation is of type tFilterOperation and gives expected warning or errors, if I add some trash branch */
  | `IN => Js.log("in was received")
  | `OR => Js.log("or was received")
  | `NOTIN => Js.log("notin was received")
  };
};

This is compiled to this JS:

function requestOldFilters(oldFilterJson) {
  var operation = oldFilterJson.operation;
  if (operation !== 17699) {
    if (operation >= 498669464) {
      console.log("notin was received");
      return (/* () */0
      );
    } else {
      console.log("in was received");
      return (/* () */0
      );
    }
  } else {
    console.log("or was received");
    return (/* () */0
    );
  }
}

Now the problem is, that operation is “IN” in runtime, but ReasonML compiled switch case to integers.

Is this expected, and I have to use tFilterOperationFrom[To]Js somehow?