次の ReasonML タイプがあるとします。
type xEntry = {title: string};
type yEntry = {value: int};
type entry =
| X(xEntry)
| Y(yEntry);
そして、次の値を JavaScript 側にエクスポートしたいと考えています。
/* Input */
let value = [
X({title: "foo"}),
Y({value: 123})
];
次の構造として:
/* Expected output */
[{"type": "X", "title": "foo"},
{"type": "Y", "value": 123}]
次のコードでほぼ達成できます。
[@bs.deriving abstract]
type jsXEntry = {
[@bs.as "type"]
type_: string,
title: string,
};
[@bs.deriving abstract]
type jsYEntry = {
[@bs.as "type"]
type_: string,
value: int,
};
type jsEntry =
| JsX(jsXEntry)
| JsY(jsYEntry);
let fromEntry = entry =>
switch (entry) {
| X(v) => JsX(jsXEntry(~type_="X", ~title=v.title))
| Y(v) => JsY(jsYEntry(~type_="Y", ~value=v.value))
};
let convertToJs = (entries: list(entry)): Js.Array.t(jsEntry) =>
Array.map(fromEntry, ArrayLabels.of_list(entries));
残念ながら(しかし当然のことながら)次の結果が得られます。
/* convertToJs(value) */
[ [ { type: 'X', title: 'foo' }, tag: 0 ],
[ { type: 'Y', value: 123 }, tag: 1 ] ]
この結果には、タグ付けされたレコード (属性を持つ単一要素の配列tag
) が含まれていますが、これは私が探しているものではありません。
JavaScript 側で変換関数を記述してそれを取り除くこともできますが、ReasonML から適切な構造を直接生成することをお勧めします。
%bs.raw
また、できればコンストラクトの使用は避けたいと思います。
上部に表示されている期待される出力を生成するにはどうすればよいですか?