Your simplified example opens a loop hole:
type something =
| A
| B;
[@bs.deriving abstract]
type someJs = {
a: Js.undefined(bool),
b: Js.undefined(bool)
};
let makeJsA = (v) => someJs(~a=Js.Undefined.return(v), ~b=Js.Undefined.empty);
let makeJsB = (v) => someJs(~b=Js.Undefined.return(v), ~a=Js.Undefined.empty);
let doSomething = (s) =>
switch s {
| A => makeJsA(true)
| B => makeJsB(true)
};
So on this side it is the same type (someJs
).
PS: scratch that:
> let f = () => ({a: true, b: undefined});
undefined
> let g = () => ({a: undefined, b: true});
undefined
> let objA = f();
undefined
> let objB = g();
undefined
> Object.getOwnPropertyNames(objA);
(2) ["a", "b"]
> Object.getOwnPropertyNames(objB);
(2) ["a", "b"]
When I used Js.log(doSomething(B))
in https://reasonml.github.io/en/try the console gave me {"b":true}
.
type something =
| A
| B;
let makeJs = (k, v) => Js.Dict.fromList([(k, v)]);
let doSomething = (s) =>
switch s {
| A => makeJs("a", true)
| B => makeJs("b", true)
};