как правильно обрабатывать тип результата вызова необработанной функции js в bucklescript

Bucklescript позволяет определять необработанные вызовы функций js, но мне не ясно, как следует обрабатывать возвращаемый тип. Кажется, можно использовать любой тип, и он все равно будет работать. Например, этот код компилируется и работает без проблем:

let f = [%raw {|
  function() {
    return 4;
  }
|}]

let x : (string option) list = f ()

Компилятор не будет жаловаться, что x имеет тип (string option) list или любой другой поддельный тип. Обычно я просто полагался бы на определение типа, но я хочу присвоить результат необработанного вызова функции js полю в структуре, поэтому мне нужно определить тип для этого поля в определении типа структуры. Кажется, я также могу использовать любой тип, и он все равно будет работать. Это ожидаемое поведение? Есть ли какие-то рекомендации по работе с этими случаями?


person yewang    schedule 30.01.2019    source источник
comment
См. reasonml.github.io/docs/en/interop.html.   -  person coredump    schedule 30.01.2019


Ответы (1)


Да, это ожидаемое поведение. Компилятор не пытается понять содержимое блоков raw, что делает их использование в целом довольно опасным. Если есть синтаксическая ошибка, компилятор не будет жаловаться.

Алгоритм вывода типа всегда будет пытаться вывести наиболее общий тип, который без каких-либо подсказок в противном случае будет... чем угодно. Он даже не предполагает, что это функция, так как это не обязательно.

%raw — это выражение, которое может быть аннотировано типом, как и любое другое выражение. Магия происходит внутри него, а не снаружи. Вы можете указать тип выражения напрямую:

let f = ([%raw {|
  function() {
    return 4;
  }
|}] : unit -> int)

или на привязке, как вы делаете с x:

let f : unit -> int = [%raw {|
  function() {
    return 4;
  }
|}]
person glennsl    schedule 30.01.2019