Skip to content

Commit 12193fc

Browse files
committed
editing pass
1 parent 98b75ec commit 12193fc

File tree

1 file changed

+20
-18
lines changed

1 file changed

+20
-18
lines changed

pages/docs/manual/latest/module-functions.mdx

+20-18
Original file line numberDiff line numberDiff line change
@@ -7,23 +7,25 @@ canonical: "/docs/manual/latest/module-functions"
77
# Module Functions
88

99
Module functions can be used to create modules based on types, values, or functions from other modules.
10-
This is a powerful tool that can be used to created abstractions and reusable code that might not be possible with functions, or might have a runtime cost if done with functions.
10+
This is a powerful tool that can be used to create abstractions and reusable code that might not be possible with functions, or might have a runtime cost if done with functions.
11+
12+
This is an advanced part of ReScript and you can generally get by with normal values and functions.
1113

1214
## Quick example
13-
Next.js has a `useNavigation` hook that returns an unknown type,
14-
and it's up to the developer to add in a type annotation to define the type of the parameters returned by the hook.
15+
Next.js has a `useParams` hook that returns an unknown type,
16+
and it's up to the developer in TypeScript to add a type annotation for the parameters returned by the hook.
1517
```TS
1618
const params = useParams<{ tag: string; item: string }>()
1719
```
1820

19-
Instead of having to add the type annotation every time you use the hook, you can create a module function that will return a typed response for the `useNavigation` hook.
21+
In ReScript we can create a module function that will return a typed response for the `useParams` hook.
2022
<CodeTab labels={["ReScript", "JS Output"]}>
2123
```res example
2224
module Next = {
2325
// define our module function
24-
module MakeNavigation = (Params: { type t }) => {
26+
module MakeParams = (Params: { type t }) => {
2527
@module("next/navigation")
26-
external useNavigation: unit => Params.t = "useNavigation"
28+
external useParams: unit => Params.t = "useParams"
2729
/* You can use values from the function parameter, such as Params.t */
2830
}
2931
}
@@ -32,21 +34,21 @@ module Component: {
3234
@react.component
3335
let make: unit => Jsx.element
3436
} = {
35-
// Create a module that matches the module type expected by Next.MakeNavigation
36-
module Params = {
37+
// Create a module that matches the module type expected by Next.MakeParams
38+
module P = {
3739
type t = {
3840
tag: string,
3941
item: string,
4042
}
4143
}
4244
43-
// Create a new module using the Params module we created and the Next.MakeNavigation module function
44-
module Navigation = Next.MakeNavigation(Params)
45+
// Create a new module using the Params module we created and the Next.MakeParams module function
46+
module Params = Next.MakeParams(P)
4547
4648
@react.component
4749
let make = () => {
4850
// Use the functions, values, or types created by the module function
49-
let params = Navigation.useNavigation()
51+
let params = Params.useParams()
5052
<div>
5153
<p>
5254
{React.string("Tag: " ++ params.tag /* params is fully typed! */)}
@@ -62,16 +64,16 @@ module Component: {
6264
import * as $$Navigation from "next/navigation";
6365
import * as JsxRuntime from "react/jsx-runtime";
6466

65-
function MakeNavigation(Params) {
67+
function MakeParams(Params) {
6668
return {};
6769
}
6870

6971
var Next = {
70-
MakeNavigation: MakeNavigation
72+
MakeParams: MakeParams
7173
};
7274

7375
function Playground$Component(props) {
74-
var params = $$Navigation.useNavigation();
76+
var params = $$Navigation.useParams();
7577
return JsxRuntime.jsxs("div", {
7678
children: [
7779
JsxRuntime.jsx("p", {
@@ -107,15 +109,15 @@ let getEnv = () => {
107109
env
108110
}
109111
```
110-
It's not possible to define types for this that will work for every project, so we just set it as 'a and the consumer of our library can define the return type when they use the function.
112+
It's not possible to define types for this that will work for every project, so we just set it as 'a and the consumer of our library can define the return type.
111113
```res
112114
type t = {"LOG_LEVEL": string}
113115
114116
let values: t = getEnv()
115117
```
116118
This isn't great and it doesn't take advantage of ReScript's type system and ability to use types without type definitions, and it can't be easily shared across our application.
117119

118-
We can instead create a module function that can return a module that has contains a `getEnv` hook that has a typed response.
120+
We can instead create a module function that can return a module that has contains a `getEnv` function that has a typed response.
119121
```res
120122
module MakeEnv = (
121123
E: {
@@ -129,7 +131,7 @@ module MakeEnv = (
129131
}
130132
}
131133
```
132-
And now consumers of our library can define the types and create a custom version of the hook just for their application.
134+
And now consumers of our library can define the types and create a custom version of the hook for their application.
133135
Notice that in the JavaScript output that the `import.meta.env` is used directly and doesn't require any function calls or runtime overhead.
134136

135137
<CodeTab labels={["ReScript", "JS Output"]}>
@@ -249,7 +251,7 @@ function Person$1(props) {
249251

250252
## Dependency injection
251253
Module functions can be used for dependency injection.
252-
Here's an example of injecting in a some config values into a set of functions to access a database.
254+
Here's an example of injecting in some config values into a set of functions to access a database.
253255
<CodeTab labels={["ReScript", "JS Output"]}>
254256
```res
255257
module type DbConfig = {

0 commit comments

Comments
 (0)