文档 / GenType / 用法

用法

genType 操作两种类型的实体: typesvalues。 它们都可以从 ReScript 导出 到 JS,或者从 JS 导入 到 ReScript。 主要的注解是 @genType,默认情况下是 导出

导出和导入类型

下面将一个函数类型 callback 导出到JS:

RES
@genType type callback = ReactEvent.Mouse.t => unit

从 JS 模块 MyMath.ts(或 MyMath.js)中导入名为 complexNumber 的类型,使用 @genType.import 注解:

RES
@genType.import("./MyMath") type complexNumber

这个导入的类型将被 ReScript.Ω 视为不透明的。

导出和导入值

导出一个函数 callback 到 JS:

RES
@genType let callback = _ => Js.log("Clicked");

要在 JS 端重命名函数并将其导出为 CB,请使用

RES
@genType @genType.as("CB") let callback = _ => Js.log("Clicked");

或者更紧凑的写法

RES
@genType("CB") let callback = _ => Js.log("Clicked");

从 JS 模块 MyMath.ts (或 MyMath.js) 中导入函数 realValue

RES
@genType.import("./MyMath") /* JS module to import from. */ /* Name and type of the JS value to import. */ external realValue: complexNumber => float = "realValue";

注意: 当 genType 版本 < 2.17.0 或 bucklescript 版本 < 5.0.0, 必须加上一行 @bs.module 和当前文件名。 请看旧版 README.

因为 external 关键字,从上下文可以清楚地看出这是一个导入,所以你也可以只使用 @genType 而忽略 .import

要导入一个默认的 JS 导出,在 @genType.import 中使用第二个参数,例如 @genType.import(("./MyMath", "default"))

相似的,导入具有不同 JS 名称的值,使用类似 @genType.import(("./MyMath", "ValueStartingWithUpperCaseLetter")) 的方法。

导入嵌套值,例如 Some.Nested.value, 使用类似 @genType.import(("./MyMath", "Some.Nested.value")) 的方法。

接口 (.resi) 和实现 (.res) 文件

如果 Foo.resiFoo.res 都存在,注解会从 Foo.resi 中取。局部模块也是如此:如果存在,则模块类型优先。

可以通过在 Foo.resi 顶部添加注解 @genType.ignoreInterface 来覆盖该行为。用例:向 JS 暴露实现细节,而不向 ReScript 暴露。

类型扩展和 @genType.opaque

如果导出的类型 persons 在其定义中引用了其他类型,那么这些类型在默认情况下也会被导出,只要它们定义在同一个文件中:

RES
type name = string type surname = string type person = {name: name, surname: surname} @genType type persons = array<person>;

但是,如果你想在 JS 中隐藏 namesurname 是字符串的事实,你可以用 @genType.opaque 注解:

RES
@genType.opaque type name = string @genType.opaque type surname = string type person = { name, surname, }; @genType type persons = array<person>;

重命名,@genType.as 和对象 mangling 约定。

默认情况下,具有给定名称的实体将以相同的名称导出/导入。但是,你可能希望更改在 JS 端出现的名称。

注意:从ReScript 7.0.0 版本开始,@genType.as 不鼓励使用在记录字段, 因为它会产生运行时转换开销。使用零开销的 @bs.as 替代它。

例如,对于名称为关键字的记录字段,例如 type

RES
@genType type shipment = { date: float, @genType.as("type") type_: string, }

对象字段名遵循 ReScript 的 mangling 约定:

删除后缀的 “__”。 否则,当前缀 “_” 后跟着大写字母或关键字时,删除前缀。

类似的对象例子是:

RES
@genType type shipment = { "date": float, "_type": string, }

或者 "type__": string,也是一样的。

函数和函数组件对于标签参数也遵循 mangling 约定:

RES
@genType let exampleFunction = (~_type) => "type: " ++ _type @genType @react.component let exampleComponent = (~_type) => React.string("type: " ++ _type)

可以对函数使用 @genType.as,尽管这只是为了向后兼容,并且不能在函数式组件上使用:

RES
@genType let functionWithGenTypeAs = (~date: float) => @genType.as("type") (~type_: string) => ...

注意: 由于技术原因,在函数的第一个参数上使用 @genType.as 是不可能的。

依赖项目 / 库

ReScript 依赖项在 bs-dependencies 中指定。

例如,如果依赖项是 "bs-dependencies": ["somelibrary"],并且 somelibrary 包含 Common.res,下面的代码会在库中查找 foo 的类型:

RES
@genType let z = Common.foo;

还支持形式为 @demo/somelibrary 的作用域包。

注意: 库必须是和 genType 生成的 .gen.ts 文件一起发布的。