Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit a0a2963

Browse files
committedDec 5, 2023
WIP: 4d7cc30 Merge pull request #750 from rescript-association/uncurried-docs
1 parent a2a9619 commit a0a2963

File tree

3 files changed

+130
-141
lines changed

3 files changed

+130
-141
lines changed
 

‎pages/docs/manual/latest/build-configuration.mdx

+10-8
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ Your source files need to be specified explicitly (we don't want to accidentally
3434
"sources": ["src", "examples"]
3535
}
3636
```
37+
3738
```json
3839
{
3940
"sources": {
@@ -59,22 +60,22 @@ You can mark your directories as dev-only (for e.g. tests). These won't be built
5960

6061
```json
6162
{
62-
"sources" : {
63-
"dir" : "test",
64-
"type" : "dev"
63+
"sources": {
64+
"dir": "test",
65+
"type": "dev"
6566
}
6667
}
6768
```
6869

69-
You can also explicitly allow which modules can be seen from outside. This feature is especially useful for library authors who want to have a single entry point for their users.
70+
You can also explicitly allow which modules can be seen from outside. This feature is especially useful for library authors who want to have a single entry point for their users.
7071
Here, the file `src/MyMainModule.res` is exposed to outside consumers, while all other files are private.
7172

7273
```json
7374
{
7475
"sources": {
7576
"dir": "src",
7677
"public": ["MyMainModule"]
77-
},
78+
}
7879
}
7980
```
8081

@@ -140,7 +141,8 @@ This configuration only applies to you, when you develop the project. When the p
140141
## suffix
141142

142143
**Since 11.0**: The suffix can now be freely chosen. However, we still suggest you stick to the convention and use
143-
one of the following:
144+
one of the following:
145+
144146
- `".js`
145147
- `".mjs"`
146148
- `".cjs"`
@@ -151,11 +153,11 @@ one of the following:
151153
- `".bs.mjs"`
152154
- `".bs.cjs"`
153155

154-
Currently prefer `.bs.js` for now.
156+
Currently prefer `.res.js` for now.
155157

156158
### Design Decisions
157159

158-
Generating JS files with the `.bs.js` suffix means that, on the JS side, you can do `const myReScriptFile = require('./theFile.bs')`. The benefits:
160+
Generating JS files with the `.res.js` suffix means that, on the JS side, you can do `const myReScriptFile = require('./theFile.res')`. The benefits:
159161

160162
- It's immediately clear that we're dealing with a generated JS file here.
161163
- It avoids clashes with a potential `theFile.js` file in the same folder.

‎pages/docs/manual/latest/gentype-getting-started.mdx

-102
This file was deleted.

‎pages/docs/manual/latest/gentype-introduction.mdx

+120-31
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,16 @@ description: "GenType - Interoperability between ReScript and TypeScript"
44
canonical: "/docs/manual/latest/gentype-introduction"
55
---
66

7-
# GenType
7+
# ReScript & TypeScript
88

9-
`genType` is a code generation tool that lets you export ReScript values and types to use in TypeScript (TS), and import TS values and types into ReScript.
9+
The ReScript compiler includes a code generation tool that lets you export ReScript values and types to use in TypeScript (TS), and import TS values and types into ReScript. It is called `genType`.
1010

1111
Converter functions between the two runtime representations are generated when required based on the type of the values.
1212
In particular, conversion of [rescript-react](/docs/react/latest/introduction) components both ways is supported, with automatic generation of the wrappers.
1313

14-
Here's an article describing how to use `genType` as part of a migration strategy where a tree of components is gradually converted to ReScript bottom-up (old article containing Reason / BuckleScript): [Adopting Reason: strategies, dual sources of truth, and why genType is a big deal](https://medium.com/p/c514265b466d).
15-
1614
The implementation of genType performs a type-directed transformation of ReScript programs after compilation. The transformed programs operate on data types idiomatic to JS.
1715

18-
For example, a ReScript function operating on a ReScript variant `type t = | A(int) | B(string)` (which is represented as custom objects with tags at runtime) is exported to a JS function operating on the corresponding JS object of type `{ tag: "A"; value: number }
19-
| { tag: "B"; value: string }`.
16+
For example, a ReScript function operating on a ReScript variant `type t = | A(int) | B(string)` (which is represented as custom objects with tags at runtime) is exported to a JS function operating on the corresponding JS object of type `{ TAG: "A"; _0: number } | { TAG: "B"; _0: string };`.
2017

2118
## A Quick Example
2219

@@ -34,7 +31,7 @@ First we'll set up a rescript-react component:
3431
@genType
3532
type color =
3633
| Red
37-
| Blue;
34+
| Blue
3835
3936
@genType
4037
@react.component
@@ -43,44 +40,40 @@ let make = (~name: string, ~color: color) => {
4340
switch (color) {
4441
| Red => "red"
4542
| Blue => "blue"
46-
};
43+
}
4744
48-
<div className={"color-" ++ colorStr}> {React.string(name)} </div>;
49-
};
45+
<div className={"color-" ++ colorStr}> {React.string(name)} </div>
46+
}
5047
```
5148

5249
On a successful compile, `genType` will convert `src/MyComp.res` to a TS file called `src/MyComp.gen.tsx` which will look something like this:
5350

5451
```ts
5552
// src/MyComp.gen.tsx
5653

57-
/* TypeScript file generated from MyComp.res by genType. */
58-
/* eslint-disable import/first */
59-
54+
/* TypeScript file generated from Main.res by genType. */
6055

61-
import * as React from 'react';
56+
/* eslint-disable */
57+
/* tslint:disable */
6258

63-
const $$toRE818596289: { [key: string]: any } = {"Red": 0, "Blue": 1};
59+
import * as React from "react";
6460

65-
// tslint:disable-next-line:no-var-requires
66-
const MyCompBS = require('./MyComp.bs');
61+
import * as MainBS__Es6Import from "./Main.res";
62+
const MainBS: any = MainBS__Es6Import;
6763

68-
// tslint:disable-next-line:interface-over-type-literal
6964
export type color = "Red" | "Blue";
7065

71-
// tslint:disable-next-line:interface-over-type-literal
7266
export type Props = { readonly color: color; readonly name: string };
7367

74-
export const make: React.ComponentType<{ readonly color: color; readonly name: string }> = function MyComp(Arg1: any) {
75-
const $props = {color:$$toRE818596289[Arg1.color], name:Arg1.name};
76-
const result = React.createElement(MyCompBS.make, $props);
77-
return result
78-
};
68+
export const make: React.ComponentType<{
69+
readonly color: color;
70+
readonly name: string;
71+
}> = MainBS.make;
7972
```
8073

8174
genType automatically maps the `color` variant to TS via a string union type `color = "Red" | "Blue"`, and also provides all the converters to convert between the ReScript & TS representation as well.
8275

83-
Therefore way we can seamlessly use ReScript specific data structures within TS without writing the converter code by hand!
76+
Therefore we can seamlessly use ReScript specific data structures within TS without writing the converter code by hand!
8477

8578
Within our TypeScript application, we can now import and use the React component in the following manner:
8679

@@ -89,17 +82,113 @@ Within our TypeScript application, we can now import and use the React component
8982
import { make as MyComp } from "./MyComp.gen.tsx";
9083

9184
const App = () => {
92-
return (<div>
93-
<h1> My Component </h1>
94-
<MyComp color="Blue" name="ReScript & TypeScript" />
95-
</div>);
85+
return (
86+
<div>
87+
<h1> My Component </h1>
88+
<MyComp color="Blue" name="ReScript & TypeScript" />
89+
</div>
90+
);
9691
};
9792
```
9893

9994
That's it for our quick example.
10095

10196
For detailed information, head to the [Getting Started](/docs/manual/latest/gentype-getting-started) or [Usage](/docs/manual/latest/gentype-usage) section.
10297

103-
## Development
98+
## Setup
99+
100+
Since compiler v10.1, there's no need to install anything. For compiler 10.0 or older, install the binaries via `npm` (or `yarn`):
101+
102+
```
103+
npm install gentype --save-dev
104+
105+
# Verify installed gentype binary
106+
npx gentype --help
107+
```
108+
109+
Add a `gentypeconfig` section to your `rescript.json` (See [Configuration](#configuration) for details):
110+
111+
```json
112+
"gentypeconfig": {
113+
"language": "typescript",
114+
"shims": {},
115+
"generatedFileExtension": ".gen.tsx",
116+
"module": "es6",
117+
"debug": {
118+
"all": false,
119+
"basic": false
120+
}
121+
}
122+
```
123+
124+
## Configuration
125+
126+
Every `genType` powered project requires a configuration item `"gentypeconfig"`
127+
at top level in the project's `rescript.json`. The configuration has following
128+
structure:
129+
130+
```json
131+
//...
132+
"gentypeconfig": {
133+
"language": "typescript",
134+
"generatedFileExtension": ".gen.tsx",
135+
"module": "es6" | "commonjs",
136+
"shims": {
137+
"ReasonReact": "ReactShim"
138+
}
139+
}
140+
```
141+
142+
- **generatedFileExtension**
143+
144+
- File extension used for genType generated files (defaults to `.gen.tsx`)
145+
146+
- **language**
147+
148+
- `"typescript"` : the `language` setting is not required from compiler v10.1
149+
150+
- **module**
151+
152+
- Module format used for the generated `*.gen.tsx` files (supports `"es6"` and `"commonjs"`)
153+
154+
- **shims**
155+
- Required only if one needs to export certain basic ReScript data types to JS when one cannot modify the sources to add annotations (e.g. exporting ReScript lists), and if the types are not first-classed in genType.
156+
- Example: `Array<string>` with format: `"RescriptModule=JavaScriptModule"`
157+
158+
## Adding Shims
159+
160+
A shim is a TS file that provides user-provided definitions for library types.
161+
162+
Configure your shim files within `"gentypeconfig"` in your [`rescript.json`](https://github.com/rescript-lang/rescript-compiler/blob/master/jscomp/gentype_tests/typescript-react-example/rescript.json), and add relevant `.shims.ts` files in a directory which is visible by ReScript e.g. [`src/shims/`](https://github.com/rescript-lang/rescript-compiler/tree/master/jscomp/gentype_tests/typescript-react-example/src/shims). An example shim to export ReactEvent can be found [here](https://github.com/rescript-lang/rescript-compiler/blob/master/jscomp/gentype_tests/typescript-react-example/src/shims/ReactEvent.shim.ts).
163+
164+
## Testing the Whole Setup
165+
166+
Open any relevant `*.res` file and add `@genType` annotations to any bindings / values / functions to be used from JavaScript. If an annotated value uses a type, the type must be annotated too. See e.g. [Hooks.res](https://github.com/reason-association/genType/blob/master/examples/typescript-react-example/src/Hooks.res).
167+
168+
Save the file and rebuild the project via `npm run bs:build` or similar. You should now see a `*.gen.tsx` file with the same name (e.g. `MyComponent.res` -> `MyComponent.gen.tsx`).
169+
170+
Any values exported from `MyComponent.res` can then be imported from JS. For example:
171+
172+
```js
173+
import MyComponent from "./components/MyComponent.gen";
174+
```
175+
176+
## Examples
177+
178+
We prepared some examples to give you an idea on how to integrate `genType` in your own project. Check out the READMEs of the listed projects.
179+
180+
- [typescript-react-example](https://github.com/rescript-lang/rescript-compiler/tree/master/jscomp/gentype_tests/typescript-react-example)
181+
182+
## Experimental features
183+
184+
These features are for experimentation only. They could be changed/removed any time, and not be considered breaking changes.
185+
186+
- Export object and record types as interfaces. To activate, add `"exportInterfaces": true` to the configuration. The types are also renamed from `name` to `Iname`.
187+
188+
- Emit prop types for the untyped back-end. To activate, add `"propTypes": true` and `"language": "untyped"` to the configuration.
189+
190+
## Limitations
191+
192+
- **in-source = true**. Currently only supports ReScript projects with [in-source generation](/docs/manual/latest/build-configuration#package-specs) and `.bs.js` file suffix.
104193

105-
Since ReScript v10.1, genType is part of the compiler's [GitHub repository](https://github.com/rescript-lang/rescript-compiler).
194+
- **Limited namespace support**. Currently there's limited [namespace](/docs/manual/latest/build-configuration#name-namespace) support, and only `namespace:true` is possible, not e.g. `namespace:"custom"`.

0 commit comments

Comments
 (0)
Please sign in to comment.