diff --git a/README.md b/README.md index 159e7f594..9e3834b43 100644 --- a/README.md +++ b/README.md @@ -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: _ =>
"Click me"->ReasonReact.string
, +}; +``` + +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 @@ -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.