【问题标题】:How to write reasonml binding for a union type如何为联合类型编写 reasonml 绑定
【发布时间】:2018-09-12 23:57:44
【问题描述】:

我正在尝试为 https://github.com/oblador/react-native-keychain/blob/master/typings/react-native-keychain.d.ts#L76 编写绑定

getGenericPassword 如果出错则返回false,否则返回object (credentials)。我不确定这种联合类型是否可以合理地表示,但更好的 API 将是一个选项(选项(凭据))的结果。但是,如何在绑定文件中转换 Promise<boolean | credentials> -> Js.Promise.t(option(credentials))。下面是一个模板。

感谢您的帮助。

[@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)) = "";

【问题讨论】:

    标签: ocaml ffi reason bucklescript union-types


    【解决方案1】:

    您可以使用Js.Types.classify 来获取值的运行时类型。

    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)
               }
             )
        );
    

    这里maybeCredentials被定义并用作中间类型。

    然后我们定义一个与绑定同名的函数,这将“隐藏”该名称并防止直接使用绑定以支持我们的“覆盖”。但是,覆盖范围内我们仍然可以使用绑定。

    然后我们调用Js.Types.classify 来获取返回值的运行时类型。如果它是一个对象,我们使用Obj.magic 将抽象obj_type 转换为我们的credentials 类型(从函数的返回类型推断),并将其包装在option 中。对于任何其他类型,我们返回None

    顺便说一下,这种“类型”被称为无标签联合。作为生产者和消费者,我在bucklescript-cookbook 中写了一些使用不同策略来处理这些问题的示例。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-02-18
      • 2019-02-05
      • 1970-01-01
      • 2015-11-30
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多