Ошибка типа при рендеринге после обещания

Я пытаюсь визуализировать компонент с разумной реакцией после получения данных из выборки, но получаю ошибку типа. Это мой код:

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), и он работает, я пытаюсь проверить тип Js.log и render (передавая их вызов функции, которая принимает int и наблюдает за ошибкой), и они оба unit

В чем моя ошибка? и есть ли что-то вроде toplevel / utop для Reason? На самом деле это очень помогает в OCaml


person SHI1485    schedule 23.01.2018    source источник


Ответы (1)


В вашем коде есть несколько проблем:

  1. Fetch.Response.json возвращает Js.Json.t (завернутый в обещание), указывая, что структура данных неизвестна системе типов и требует декодирования. Вы можете сделать это, например, с помощью bs-json.

  2. Js.Promise.resolve принимает любое значение и оборачивает это значение в Js.Promise.t. Но поскольку Js.Promise.then_ уже возвращает обещание, теперь у вас есть обещание, заключенное в обещание. Поэтому вам следует просто удалить |> 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.

Практическое правило: не предполагайте, а комментируйте.

Изменить: чтобы ответить на вопрос верхнего уровня / ответа: существует верхний уровень для Reason, называемый rtop, но он не работает с API-интерфейсами BuckleScript и JavaScript. Существует также игровая площадка Reason, которая работает с BuckleScript и JS API, но не возможность загружать внешние библиотеки.

person glennsl    schedule 23.01.2018