用法
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
文件一起发布的。