Typing for %raw block

Hi,
I want to write some typings for function in %raw block. At the moment I have:

let runApi = %raw(`
  function(api, method) {
    api[method]()
  }
`)

So I did:

let runApi: ({..}, string) => unit = %raw(`
  function(api, method) {
    api[method]()
  }
`)

but the compiler doesn’t like {..}, and throws:

This expression’s type contains type variables that can’t be generalized:
({_…}, string) => string

ReScript Playground example (rescript-lang.org)
Is it possible to write such a type?

This is related a few things happening at once: there’s a polymorphic type that is possibly mutable, the runApi value is being exported, and, because of the raw block, the compiler is extra conservative because it can’t make any guarantees about what happens inside it.

There are a couple of ways you can fix this error.

You can use a type that isn’t polymorphic, for example a closed object:

let runApi: ({"a": string}, string) => unit = %raw(`
  function(api, method) {
    api[method]()
  }
`)

You can hide the function in the interface, so it isn’t exported.

module M: {
  // interface goes here
} = {
  let runApi: ({..}, string) => unit = %raw(`
  function(api, method) {
    api[method]()
  }
`)
}
3 Likes