OK first things first in labJsonDecoder.re
, when you get a JSON file as an external, you need to type it as Js.Json.t
, not Js.t({..})
, because the former tells Reason that this is a raw JSON structure to be decoded, but the latter tells Reason that it’s an already-decoded JavaScript object. Since it’s actually JSON, treating it as a JavaScript object is not type-safe because at runtime, any of the fields which you try to get out of it may not be present.
As an aside, I see you’ve defined an option map function, if you’re using a recent bs-platform you can use Belt.Option.map
instead.
Another thing, normally you would use type ... and ...
style when the type definitions must recursively refer to each other; in this case they don’t, so you don’t need and
. Also, hover
and active
have the same definition–you may be able to unify them.
I see you also have something like Json.Decode.(decodeProps)
in a couple of places, you don’t need the local-opened module in these cases because the names inside the parens (e.g. decodeProps
) are already in scope.
Finally, the JSON decode functions, I’m seeing some errors in how they’re implemented. JSON decoder functions must all take an input of type Js.Json.t
and return an output of the type according to your implementation. In your implementation I’m seeing the inputs are typed as the various record types that you’ve defined. I expect this should throw a type error immediately. I’m not confident that the error you’re getting here is the correct one because it seems to be coming from Merlin; I recommend running this in command line bsb and looking at the output.
Once you correctly type the lab.json
file as a Js.Json.t
, you can define a decoder for it that grabs the exact data you need out of its components
field. In fact, you may not even need to define all these record types, you could just decode into Js.t
objects. It really depends on if you need the specific properties of record types: immutable update, nominal typing, etc.
If you’re having trouble with writing decoders I recommend starting with a small sample JSON file, writing a decoder for it to get the intuition right, then build your way up. Ideally at some point, we’ll have JSON derivation codegen tools in Reason but right now it’s manual…