Skip to content
This repository has been archived by the owner on Nov 13, 2023. It is now read-only.

Commit

Permalink
README: explain import/export, value/type, type expansion/rename.
Browse files Browse the repository at this point in the history
This is the documentation part of the overall cleanup proposed in #70.
  • Loading branch information
cristianoc committed Oct 29, 2018
1 parent a2e66a8 commit 2396bc3
Showing 1 changed file with 136 additions and 1 deletion.
137 changes: 136 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,141 @@ We prepared some examples to give you an idea on how to integrate `genType` in y

# Documentation

## Introduction

`genType` operates on two kinds of entities: *types* and *values*.
Each can be *exported* from Reason to JS, or *imported* into Reason from JS.
The main annotation is `@genType`, which by default means *export*.

#### Export and Import Types
The following exports a function type `callback` to JS:

```reason
[@genType]
type callback = ReactEvent.Mouse.t => unit;
```

To instead import a type called `complexNumber` from JS module `MyMath.ts` (or `MyMath.js`), use the `@genType.import` annotation:

```reason
[@genType.import "./MyMath"]
type complexNumber;
```
This imported type will be treated as opaque by Reason.

#### Export and Import Values

To export a function `callback` to JS:

```reason
[@genType]
let callback = _ => Js.log("Clicked");
```

To import a function `realValue` from JS module `MyMath.ts` (or `MyMath.js`):

```reason
[@genType.import "./MyMath"] /* This is the module to import from. */
[@bs.module "./WrapJsValue"] /* This must always be the name of the current module. */
/* Name and type of the JS value to import. */
external realValue: complexNumber => float = "";
```

Because of the `external` keyword, it's clear from context that this is an import, so you can also just use `@genType` and omit `.import`.

#### Export and Import React Components

To export a ReasonReact component to JS, and automatically generate a wrapper for it, simply annotate the `make` function:


```reason
[@genType]
let make = (~onClick: callback, _children) => {
...component,
render: _ => <div onClick> "Click me"->ReasonReact.string </div>,
};
```

To import and wrap a ReactJS component for use by ReasonReact, the type of the `make` function is the only information required:


```reason
[@genType.import "./MyBanner"] /* Module with the JS component to be wrapped. */
[@bs.module "./MyBannerWrapper"] /* This must always be the name of the current module. */
/* The make function will be automatically generated from the types below. */
external make:
(~show: bool, ~message: option(message)=?, 'a) =>
ReasonReact.component(
ReasonReact.stateless,
ReasonReact.noRetainedProps,
ReasonReact.actionless,
) =
"";
```

The type of `make` must have a named argument for each prop in the JS component. Optional props have option type. The `make` function will be generated by `genType`.

#### Type Expansion and @genType.opaque
If an exported type `persons` references other types in its definition, those types are also exported by default, as long as they are defined in the same file:


```reason
type name = string;
type surname = string;
type person = {name:name, surname:surname};
[@genType]
type persons = array(person);
```

If however you wish to hide from JS the fact that `name` and `surname` are strings, you can do it like this:

```reason
[@genType.opaque]
type name = string;
[@genType.opaque]
type surname = string;
type person = {
name,
surname,
};
[@genType]
type persons = array(person);
```

#### Renaming and @genType.as
By default, entities with a given name are exported/imported with the same name. However, you might wish to change the appearence of the name on the JS side.
For example, in the case of a Reason keyword, such as `type`:

```reason
[@genType]
type shipment = {
date: float,
[@genType.as "type"]
type_: string,
};
```

Or in the case of components:

```reason
[@genType]
let make =
(~date: float) => [@genType.as "type"] (~type_: string) => ...
```

**NOTE** For technical reasons, it is not possible to rename the first argument of a function (it will be fixed once bucklescript supports OCaml 4.0.6).

You will also need to reach out for renaming when importing a capitalized type from JS, since types in Reason cannot be capitalized:

```reason
[@genType.import "./MyMath"]
[@genType.as "ComplexNumber"]
type complexNumber;
```

## Configuration

Expand Down Expand Up @@ -229,7 +364,7 @@ npm run build
This will create the binary `lib/bs/native/gentype.native`, which is the executable that BuckleScript is supposed to use via `BS_CMT_POST_PROCESS_CMD`.
## Automated Releases (recommended - Maintainers only)
## Automated Releases (for Maintainers)
The project is compatible with the [`npm version`](https://docs.npmjs.com/cli/version) workflow. After using the `npm version [major|minor|patch|...]` command, npm will automatically tag the current commit, bump all the necessary version numbers (also the number in `src/Version.re`) and push it to the current remote branch.
Expand Down

0 comments on commit 2396bc3

Please sign in to comment.