I am trying to write bindings for https://github.com/oblador/react-native-keychain/blob/master/typings/react-native-keychain.d.ts#L76
getGenericPassword returns false
if an error, else an object
(credentials
). I am not sure this union type can be represented in reason, but a better API would be the result an option (option(credentials)). But, how can I convert Promise<boolean | credentials>
-> Js.Promise.t(option(credentials))
in the binding file. Below is a template.
Thanks for your help.
[@bs.deriving abstract]
type credentials = {
service: string,
username: string,
password: string,
};
/* TODO convert the actual return value
Js.Promise.t(option(credentials)) to more reason type
Js.Promise.t(option(credentials)) */
[@bs.module "react-native-keychain"] [@bs.scope "default"]
external getGenericPassword: unit => Js.Promise.t(option(credentials)) = "";
You can use Js.Types.classify
to get the runtime type of a value.
type maybeCredentials;
[@bs.module "react-native-keychain"] [@bs.scope "default"]
external getGenericPassword: unit => Js.Promise.t(maybeCredentials) = "";
let getGenericPassword: unit => Js.Promise.t(option(credentials)) =
() =>
Js.Promise.(
getGenericPassword()
|> then_(maybeCredentials =>
switch (Js.Types.classify(maybeCredentials)) {
| JSObject(obj) => resolve(Some(obj |> Obj.magic))
| _ => resolve(None)
}
)
);
Here maybeCredentials
is defined and used as an intermediate type.
We then define a function with the same name as the binding, which will "shadow" the name and prevent the binding from being used directly in favour of our "override". However, within the override we're still able to use the binding.
We then call Js.Types.classify
to get the runtime type of the returned value. If it is an object we use Obj.magic
to cast the abstract obj_type
to our credentials
type (inferred from the return type of the function), and wrap it in an option
. For any other type we return None
.
By the way, this kind of "type" is called an untagged union. I've written down a few examples using different strategies for dealing with these, as both a producer and a consumer, in bucklescript-cookbook.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With