Promise 后渲染中的类型错误
Type error in render after Promise
我在从 fetch 获取数据后尝试使用 reason-react 渲染组件,但收到类型错误。这是我的代码:
GetData.re:
let get = () => Js.Promise.(
Fetch.fetch("localhost:8000/data.json")
|> then_(Fetch.Response.json)
|> resolve
);
Main.re:
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.
我也尝试用简单的 Js.log(result)
替换 render 并且它有效,我尝试检查 Js.log
和 render
的类型(将它们的调用传递给一个接受 int
并观察错误)并且它们都是 unit
我的错误在哪里? Reason 有类似 toplevel/utop 的东西吗?它实际上在 OCaml
中有很大帮助
您的代码中有几个问题:
Fetch.Response.json
returns a Js.Json.t
(包裹在一个promise中),表示数据的结构对于类型系统是未知的,需要解码.例如,您可以使用 bs-json 来做到这一点。
Js.Promise.resolve
接受任何值并将该值包装在 Js.Promise.t
中。但是由于 Js.Promise.then_
已经 returns 一个承诺,你现在有一个包装在承诺中的承诺。因此,您应该从 get
函数中删除 |> resolve
。
类型错误会告诉您这两个问题 (list(Item.item) vs Js.Promise.t(Js.Json.t) (defined as Js.Promise.t(Js.Json.t))
),但它不会告诉您 它在哪里 "went wrong"。要缩小此类类型错误的范围,您可以注释函数和 let 绑定的类型。例如,如果您注释了 get
:
let get : Js.Promise.t(list(Item.item))) = ...
它会告诉您问题出在 get
函数中。
经验法则:不要假设,注释。
编辑:回答toplevel/repl问题:Reason有一个顶层叫做rtop
,但它不适用于BuckleScript和JavaScript API。还有 Reason playground 可以与 BuckleScript 和 JS API 一起使用,但无法加载外部库。
我在从 fetch 获取数据后尝试使用 reason-react 渲染组件,但收到类型错误。这是我的代码:
GetData.re:
let get = () => Js.Promise.(
Fetch.fetch("localhost:8000/data.json")
|> then_(Fetch.Response.json)
|> resolve
);
Main.re:
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.
我也尝试用简单的 Js.log(result)
替换 render 并且它有效,我尝试检查 Js.log
和 render
的类型(将它们的调用传递给一个接受 int
并观察错误)并且它们都是 unit
我的错误在哪里? Reason 有类似 toplevel/utop 的东西吗?它实际上在 OCaml
中有很大帮助您的代码中有几个问题:
Fetch.Response.json
returns aJs.Json.t
(包裹在一个promise中),表示数据的结构对于类型系统是未知的,需要解码.例如,您可以使用 bs-json 来做到这一点。Js.Promise.resolve
接受任何值并将该值包装在Js.Promise.t
中。但是由于Js.Promise.then_
已经 returns 一个承诺,你现在有一个包装在承诺中的承诺。因此,您应该从get
函数中删除|> resolve
。
类型错误会告诉您这两个问题 (list(Item.item) vs Js.Promise.t(Js.Json.t) (defined as Js.Promise.t(Js.Json.t))
),但它不会告诉您 它在哪里 "went wrong"。要缩小此类类型错误的范围,您可以注释函数和 let 绑定的类型。例如,如果您注释了 get
:
let get : Js.Promise.t(list(Item.item))) = ...
它会告诉您问题出在 get
函数中。
经验法则:不要假设,注释。
编辑:回答toplevel/repl问题:Reason有一个顶层叫做rtop
,但它不适用于BuckleScript和JavaScript API。还有 Reason playground 可以与 BuckleScript 和 JS API 一起使用,但无法加载外部库。