A RetroSearch Logo

Home - News ( United States | United Kingdom | Italy | Germany ) - Football scores

Search Query:

Showing content from https://rescript-lang.org/docs/manual/latest/typescript-integration below:

TypeScript | ReScript Language Manual

ReScript & TypeScript

The ReScript compiler includes a code generation tool that lets you export ReScript values and types to use in TypeScript, and import TypeScript values and types into ReScript. It is called "genType".

The implementation of genType performs a type-directed transformation of ReScript programs after compilation. The transformed programs operate on data types idiomatic to TypeScript.

For example, a ReScript variant (which is represented as custom objects with tags at runtime):

RES

@genType type t = | A(int) | B(string)

is exported to a TypeScript type:

TS

type t = { TAG: "A"; _0: number } | { TAG: "B"; _0: string };

Let's assume we are working on a TypeScript codebase and we want to integrate a single ReScript function.

We want to be able to import the function like any other one in our existing TypeScript code, but we also want to preserve all the ReScript types in the TypeScript type system.

That's exactly what genType was made for!

First we'll set up a function:

RES

@genType type color = | Red | Blue @genType let printColorMessage = (~color, ~message) => { let prefix = switch color { | Red => "\x1b[91m" | Blue => "\x1b[94m" } let reset = "\x1b[0m" Console.log(prefix ++ message ++ reset) }

On a successful compile, genType will convert src/Color.res to a TypeScript file called src/Color.gen.tsx which will look something like this:

TS

import * as ColorJS from "./Color.res.js"; export type color = "Red" | "Blue"; export const printColorMessage: (color: color) => void = ColorJS.printColorMessage as any;

genType automatically maps the color variant to TS via a string union type "Red" | "Blue".

Within our TypeScript application, we can now import and use the function in the following manner:

TS

import { printColorMessage } from "./Color.gen.tsx"; printColorMessage("Red", "Hello, genType!");

Since ReScript 11.0.0 modules can be annotated with @genType as well. In that case, all types and values of the module will be converted to TS types. Example:

ReScriptTypeScript Output

@genType
module Size = {
  type t =
    | Small
    | Medium
    | Large

  let getNum = (size: t) =>
    switch size {
    | Small => 1.
    | Medium => 5.
    | Large => 10.
    }
}

Add a gentypeconfig section to your rescript.json (See Configuration for details).

Every genType powered project requires a configuration item "gentypeconfig" at top level in the project's rescript.json.

The minimal configuration of genType is following:

JSON

{ "gentypeconfig": { "module": "esmodule", "moduleResolution": "node", "generatedFileExtension": ".gen.tsx" } }

And don't forget to make sure allowJs is set to true in the project's tsconfig.json:

JSON

{ "compilerOptions": { "allowJs": true } }

TypeScript Module Resolutions

Make sure to set the same moduleResolution value in both rescript.json and tsconfig.json, so that the output of genType is done with the preferred module resolution.

For example if the TypeScript project uses JavaScript modules with Node16 / NodeNext module resolution:

JSON

{ "compilerOptions": { "moduleResolution": "node16" } }

Then moduleResolution in gentypeconfig should be same value:

JSON

{ "gentypeconfig": { "moduleResolution": "node16" } }

In case of the TypeScript project using Bundler module resolution, allowImportingTsExtensions should also be true:

JSON

{ "compilerOptions": { "moduleResolution": "bundler", "allowImportingTsExtensions": true } }

JSON

{ "gentypeconfig": { "moduleResolution": "bundler" } }

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.

Save the file and rebuild the project via npm run res:build or similar. You should now see a *.gen.tsx file with the same name (e.g. MyComponent.res -> MyComponent.gen.tsx).

Any values exported from MyComponent.res can then be imported from TypeScript. For example:

JS

import MyComponent from "./components/MyComponent.gen.tsx";

These features are for experimentation only. They could be changed/removed any time, and not be considered breaking changes.

A shim is a TS file that provides user-provided definitions for library types.

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.

Configure your shim files within "gentypeconfig" in your [rescript.json]:

JSON

{ "gentypeconfig": { "shims": { "Js": "Js", "ReactEvent": "ReactEvent", "RescriptPervasives": "RescriptPervasives", "ReasonReact": "ReactShim" } } }

and add relevant .shim.ts files in a directory which is visible by ReScript e.g.

├── rescript.json ├── src │ ├── shims │ │ ├── Js.shim.ts │ │ ├── ReactEvent.shim.ts │ │ └── RescriptPervasives.shim.ts

Here are some examples:

TS

export type Json_t = unknown; export type t = unknown;

TS

export type inputFocusEvent = React.FocusEvent<HTMLInputElement>;

More complete example shims can be found here.

Features related to generating runtimes were deprecated since v11 and should no longer be used.

genType does not generate anything runtime-related, and in the near future it generates definition files (*.d.ts) directly (See the roadmap).

If any runtime code is required for interoperability with JavaScript / TypeScript projects, it can be written by hand, or request a relevant features (e.g. @deriving) to the compiler.


RetroSearch is an open source project built by @garambo | Open a GitHub Issue

Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo

HTML: 3.2 | Encoding: UTF-8 | Version: 0.7.4