用法
genType 操作两种类型的实体: types 和 values。
它们都可以从 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.resi 和 Foo.res 都存在,注解会从 Foo.resi 中取。局部模块也是如此:如果存在,则模块类型优先。
可以通过在 Foo.resi 顶部添加注解 @genType.ignoreInterface 来覆盖该行为。用例:向 JS 暴露实现细节,而不向 ReScript 暴露。
类型扩展和 @genType.opaque
如果导出的类型 persons 在其定义中引用了其他类型,那么这些类型在默认情况下也会被导出,只要它们定义在同一个文件中:
REStype name = string
type surname = string
type person = {name: name, surname: surname}
@genType
type persons = array<person>;
但是,如果你想在 JS 中隐藏 name 和 surname 是字符串的事实,你可以用 @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 文件一起发布的。