.resi file throws an error even though things look right

I’m trying to add bindings for the discord.js library and running into troubles with an interface file. I’ve auto generated the interface file in vscode from the command palette and it still shows an error

This is the file stripped down to just one module for the example. Here I am just trying to make a make function with named arguments that cast to some internal object type that the library uses

type embed

module Embed = {
  type t = embed

  external asEmbed: {..} => t = "%identity"

  let make = (
    ~color:option<int>=?,
    ~title:option<string>=?,
    ~description:option<string>=?,
    ~footer:option<string>=?,
    ()
  ) => {
    "color": color->Js.Nullable.fromOption,
    "title": title->Js.Nullable.fromOption,
    "description": description->Js.Nullable.fromOption,
    "footer": footer->Belt.Option.map (f => {"text": f})->Js.Nullable.fromOption
  }->asEmbed
}

This is the interface file it’s created

type embed

module Embed: {
  type t = embed
  external asEmbed: {..} => t = "%identity"
  let make: (
    ~?color: int,
    ~?title: string,
    ~?description: string,
    ~?footer: string,
    unit,
  ) => t
}

I’ve looked it over and it looks fine to me, but rescript won’t compile because of this error:

  The implementation /bindings/DiscordJs.res
       does not match the interface/bindings/discordJs.cmi:
       ...
       In module Embed:
       Values do not match:
         let make: (
  ~?color: int,
  ~?title: string,
  ~?description: string,
  ~?footer: string,
  unit,
) => t
       is not included in
         let make: (
  ~color: int,
  ~title: string,
  ~description: string,
  ~footer: string,
  unit,
) => t

I believe this is related to this bug: https://github.com/rescript-lang/syntax/issues/459 It’s been fixed but the fix is not released yet.

The formatter emits incorrect syntax for optional arguments. This is the correct syntax:

type embed
module Embed: {
  type t = embed
  external asEmbed: {..} => t = "%identity"
  let make: (
    ~color: int=?,
    ~title: string=?,
    ~description: string=?,
    ~footer: string=?,
    unit,
  ) => t
}
2 Likes

One more thing, annotating in the implementation is redundant once you have an interface file. It’s much cleaner to get rid of those:

  let make = (
    ~color=?,
    ~title=?,
    ~description=?,
    ~footer=?,
    (),
  ) => {...
2 Likes