【问题标题】:Accessors name conflict trying to create a binding尝试创建绑定的访问器名称冲突
【发布时间】:2019-01-07 17:30:06
【问题描述】:

我正在尝试为现有的 javascript 库创建绑定,但在尝试使用属性访问功能时出现错误。

[@bs.deriving abstract]
type objA = {
  prop1: string,
  prop2: string,
  prop3: string,
};

[@bs.deriving abstract]
type objB = {
  prop2: string,
  prop4: string,
};

[@bs.module "myLib"] external getObjA: (unit) => objA = "";
[@bs.module "myLib"] external getObjB: (unit) => objB = "";

let obj = getObjA();
prop2Get(obj) |> Js.log
// ------^^^
// Error: This expression has type objA but an expression was expected of type objB

我知道这两个对象具有相同的属性名称,因此生成的函数prop2Get(...) 将被覆盖。这种情况有什么解决办法?

【问题讨论】:

  • 我建议避免使用@bs.deriving abstract,部分原因是因为此类问题令人困惑,但也因为缺乏灵活性以及生成的非常令人讨厌的属性名称。相反,我建议将Js.t 用于一次性和内部使用,它不是某些接口的一部分,并使用抽象类型和bs.get/bs.set 外部如果是的话,分开总是一个好主意与底层数据结构,尤其是外部数据结构的接口,以隔离其中的潜在变化。
  • 我认为bs.deriving abstract 与其他选项相比只有 一个 技术优势:它允许您生成具有非法 OCaml 标识符的属性名称的 js 对象。跨度>

标签: ffi reason bucklescript


【解决方案1】:

您需要命名它们。在 OCaml/Reason 中,命名空间的方法是将它们放在单独的模块中。具体来说,

module ObjA = {
  [@bs.deriving abstract] type t = {
    prop1: string,
    prop2: string,
    prop3: string,
  };

  [@bs.module "myLib"] external get: (unit) => t = "getObjA";
};

module ObjB = {
  [@bs.deriving abstract] type t = {
    prop2: string,
    prop4: string,
  };

  [@bs.module "myLib"] external get: (unit) => t = "getObjB";
};

现在,访问器也由其类型的模块命名:

() |> ObjA.get |> ObjA.prop2Get |> Js.log;

好消息是,由于模块名称用作整体名称的一部分,因此您无需在名称中重复某些内容,例如 getObjAgetObjB

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多