-
Notifications
You must be signed in to change notification settings - Fork 471
Description
With the new React Native bindings that I am creating (https://github.com/reasonml-community/bs-react-native/tree/master/bs-react-native-next), my goal is to achieve zero cost for these bindings, or as close to zero cost as it gets. Still, I would like to provide type safety for string enums.
For creating new JS objects, [@bs.obj]
combined with [@bs.string]
does the job fine (BTW, #2827 would be really nice to have, too).
However, there are also cases where I either need to pass an array of an enum type or to return an object with an enum field from a JS API (without explicitly transforming it to some Reason object with a variant field).
For these cases, my current solution is to use an abstract type for the enum and to provide the possible values in the bindings, see e.g. Easing.t in:
https://github.com/reasonml-community/bs-react-native/blob/master/bs-react-native-next/src/apis/Keyboard.re
https://github.com/reasonml-community/bs-react-native/blob/master/bs-react-native-next/src/apis/Keyboard.bs.js
Unfortunately, providing the values for the enum this way is not zero cost.
It would be great to be able to do something like
[@bs.val] external easeIn: t = "\"easeIn\"";
instead, to provide the required constant as an external value of type t. However, this gives the error
Not a valid global name "easeIn", as "easeIn" is not a valid identifier.
Another use case would be the following (binding for React Native Platform
):
type os;
[@bs.module "react-native"] [@bs.scope "Platform"] external os: os = "OS";
[@bs.val] external ios: os = "\"ios\"";
[@bs.val] external android: os = "\"android\"";
@bobzhang: Do you know of a solution? Would it be possible to relax the checks for [@bs.val]
to allow string or number constants? Or provide something like [@bs.constant]
instead?
/cc @rickyvetter @MoOx