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?