Closed
Description
Here's an overview of bs.deriving abstract
currently:
[@bs.deriving abstract]
type foo = {
high: int,
low: option(int),
};
This generates:
- An abstract type
t
- A creator function:
let foo: (~high: int, ~low: option(int)=?, unit) => t
- Getters:
high
,low
- Setters:
highSet
, highLow` - The original record type is erased
- You can annotate the labels to make the creation function/getter/setter use a different name that's otherwise invalid, e.g.
high(s)
might compile tos["aria-high"]
. - Marking a record field as mutable generates the correct setter that mutates.
The goal is that we get some nice helpers, but also that it can generate platform-agnostic code. E.g. for JS backend, we can compile that abstract type to a JS object.
The other option is to start with a creator function:
[@bs.deriving abstract]
let foo = (~high: int, ~low: option(int)=?, unit) => "";
And generate the same helpers. This one has some advantages:
- It's clear which labels are optional. Front-end might use a lot of optional args. In the current record-based deriving, if you write
low: foo
you wouldn't know whetherfoo
isoption(int)
and accidentally makelow
non-optional. - You get to specify default values. This is limited, but nice.
- You can customize the body of the function for future purposes.
- The function name is customizable.
- Likely less confusing for newcomers, because the first one has a record type which cannot be used (it's erased). So no weird errors when trying to create a value of that record type.
The drawback is that you for mutable field you'd need a new annotation.
I feel that the creation-based option might make more sense, but I'm not too sure.
Metadata
Metadata
Assignees
Labels
No labels