Bind to a function inside an object with export default

I was writing bindings to the chalk package using Deno npm specifiers.

In JS it is used like this:

import chalk from "npm:chalk@3";

console.log(chalk.blue("hello"));

This works perfectly.

In ReScript:

@module("npm:chalk@3") external blue: string => string = "blue"
blue("Hello")->Js.log

Compile to:

import * as Npmchalk3 from "npm:chalk@3";
console.log(Npmchalk3.blue("Hello"));

When I run deno run src/Demo.bs.mjs, I get the following error:

error: Uncaught TypeError: Npmchalk3.blue is not a function
console.log(Npmchalk3.blue("Hello"));
                      ^
    at file:///home/pedro/Desktop/rescript-with-deno/src/Demo.bs.mjs:5:23

I had to add @scope("default") to fix it.

@module("npm:chalk@3") @scope("default") external blue: string => string = "blue"

blue("Hello")->Js.log
import * as Npmchalk3 from "npm:chalk@3";

console.log(Npmchalk3.default.blue("Hello"));

Is there another way to do this? I didn’t find examples in the documentation.

1 Like

I believe that’s the correct way. Perhaps you could send a PR to add that technique to the documentation?

1 Like

PR: docs: bind to a function inside an object with default export by aspeddro · Pull Request #673 · rescript-association/rescript-lang.org · GitHub

1 Like

FWIW, I tend to use = ”default” for default exports, e.g.

@module(“foo/bar”)
external foo: unit => string = ”default”

Which compiles to:

import Foo from “foo/bar”

Playground:

https://rescript-lang.org/try?version=v10.1.2&code=AIWw9gJgrgNgpgCgEQDMxiQSgFBwB4AucATgHYCGMABGmAFxVSkCWBVAvAHxUDOBxzUgHMOVJBDgpysAkmzZQkWIiQAjcsSxVgPAMZgADiolSZWXIRIVq64gyasO3PgOGi1Gudnhs8o2gg4PlQAnqK2gdhAA

2 Likes