0

在我从 fetch 获取数据后,我试图用理性反应渲染一个组件,但我收到一个类型错误。这是我的代码:

获取数据.re:

let get = () => Js.Promise.(
  Fetch.fetch("localhost:8000/data.json")
  |> then_(Fetch.Response.json)
  |> resolve
);

主要内容:

let data = () =>
  GetData.get()
   |> Js.Promise.then_(result =>
      Js.Promise.resolve(
       ReactDOMRe.renderToElementWithId(
         <ItemsList itemsList=result />,
         "root"
       )
   )
 )

我收到了这个错误:

29 │ let data = () =>
30 │   GetData.get()
31 │   |> Js.Promise.then_(result =>
32 │        Js.Promise.resolve(
 . │ ...
37 │        )
38 │      );

This has type:
  (Js.Promise.t(list(Item.item))) => Js.Promise.t(unit)
But somewhere wanted:
  (Js.Promise.t(Js.Promise.t(Js.Json.t))) => 'a

The incompatible parts:
  Js.Promise.t(list(Item.item)) (defined as Js.Promise.t(list(Item.item)))
  vs
  Js.Promise.t(Js.Promise.t(Js.Json.t)) (defined as
  Js.Promise.t(Js.Promise.t(Js.Json.t)))

Further expanded:
  list(Item.item)
  vs
  Js.Promise.t(Js.Json.t) (defined as Js.Promise.t(Js.Json.t))

ninja: build stopped: subcommand failed.

我还尝试用 simple 替换 renderJs.log(result)并且它可以工作,我尝试检查Js.logand的类型render(将它们的调用传递给一个接受int并观察错误的函数)并且它们都是unit

我的错误在哪里?有没有类似顶级/ utop 的原因?它实际上对 OCaml 有很大帮助

4

1 回答 1

0

您的代码中有几个问题:

  1. Fetch.Response.json返回a Js.Json.t(包装在promise中),表示数据的结构对于类型系统来说是未知的,需要解码。例如,您可以使用bs-json来做到这一点。

  2. Js.Promise.resolve接受任何值并将该值包装在 a 中Js.Promise.t。但是由于Js.Promise.then_已经返回了一个 Promise,你现在有了一个包裹在 Promise 中的 Promise。因此,您应该|> resolve从您的get功能中删除。

类型错误会告诉您这两个问题 ( list(Item.item) vs Js.Promise.t(Js.Json.t) (defined as Js.Promise.t(Js.Json.t))),但不会告诉您“出错”的地方。要缩小这样的类型错误,您可以注释函数和 let-bindings 的类型。例如,如果您已注释get

let get : Js.Promise.t(list(Item.item))) = ...

它会向您表明问题出在get函数内部。

经验法则:不要假设,注释。

编辑:回答顶层/repl 问题:有一个名为 Reason 的顶层rtop,但它不适用于 BuckleScript 和 JavaScript API。还有一个Reason 游乐场,它可以与 BuckleScript 和 JS API 一起使用,但不能加载外部库。

于 2018-01-23T09:21:42.850 回答