GenType
genType
是一个代码生成工具,它允许你导出 ReScript 中的值和类型用于 JavaScript 中,还可以导入 JavaScript 中的值和类型到 ReScript 中。
根据值的类型生成两种表示形式之间的转换器函数。转换器可以被生成为原生 JavaScript,或者生成为 TypeScript / Flow ,从而获得类型安全的接口。 特别是,rescript-react 组件支持两种转换方式,还附带自动生成的包装器。
这里有一篇文章描述了如何使用 genType
作为迁移策略的一部分,将组件树自下而上地逐渐转换为 ReScript (包含 Reason / BuckleScript 的旧文章): Adopting Reason: strategies, dual sources of truth, and why genType is a big deal。
genType 的实现在编译完 ReScript 源码之后对 ReScript 程序执行面向类型的转换,转换后的程序操作的就是 JS 惯用的数据类型。
例如,一个在 ReScript 变体上的函数操作 type t = | A(int) | B(string)
(哪一个在运行时会表示为自定义块) 被导出到一个 JS 函数操作中对应的 JS 对象类型 { tag: "A"; value: number }
| { tag: "B"; value: string }
genType 的后端有三种配置,生成不同的输出:untyped
生成原生 JS 的包装器,typescript
生成 TypeScript,flow
生成带有 Flow 类型注解的 JS。
快速示例
假设我们正在处理一个 TypeScript (TS) 代码库,我们想集成一个单独的 rescript-react 组件。
我们希望能够像导入现有 TS 代码中的 React 组件一样,导入 rescript-react 组件,我们也想在 TS 类型系统中保留所有的 ReScript 类型(并在必要时转换不兼容的值)。
genType 就是为此而生的!
首先,我们准备一个 rescript-react 组件:
RES/* src/MyComp.res */
@genType
type color =
| Red
| Blue;
@genType
@react.component
let make = (~name: string, ~color: color) => {
let colorStr =
switch (color) {
| Red => "red"
| Blue => "blue"
};
<div className={"color-" ++ colorStr}> {React.string(name)} </div>;
};
当成功编译后,genType
会将 src/MyComp.res
转换到一个叫做 src/MyComp.gen.ts
的 TS 文件中,它看起来像这样:
TS// src/MyComp.gen.tsx
/* TypeScript file generated from MyComp.res by genType. */
/* eslint-disable import/first */
import * as React from 'react';
const $$toRE818596289: { [key: string]: any } = {"Red": 0, "Blue": 1};
// tslint:disable-next-line:no-var-requires
const MyCompBS = require('./MyComp.bs');
// tslint:disable-next-line:interface-over-type-literal
export type color = "Red" | "Blue";
// tslint:disable-next-line:interface-over-type-literal
export type Props = { readonly color: color; readonly name: string };
export const make: React.ComponentType<{ readonly color: color; readonly name: string }> = function MyComp(Arg1: any) {
const $props = {color:$$toRE818596289[Arg1.color], name:Arg1.name};
const result = React.createElement(MyCompBS.make, $props);
return result
};
genType 自动将 color
变体映射到 TS 的字符串联合类型 color = "Red" | "Blue"
,还提供了在 ReScript & TS 表示之间转换的所有转换器。
因此,我们可以在 TS 中无缝使用 ReScript 特定的数据结构,而无需手动编写转换器代码!
在我们的 TypeScript 应用程序中,我们现在可以通过以下方式导入和使用 React 组件:
TS// src/App.ts
import { make as MyComp } from "./MyComp.gen.tsx";
const App = () => {
return (<div>
<h1> My Component </h1>
<MyComp color="Blue" name="ReScript & TypeScript" />
</div>);
};
这就是我们的快速示例。
开发问题
想要贡献代码,提出 issues 或提问,请参照 GitHub 仓库 或我们的 ReScript 论坛