You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Module functions can be used to create modules based on types, values, or functions from other modules.
10
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.
11
11
12
+
## Quick example
12
13
Next.js has a `useNavigation` hook that returns an unknown type,
13
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.
14
15
```TS
@@ -96,6 +97,7 @@ export {
96
97
```
97
98
</ CodeTab>
98
99
100
+
## Sharing a type with an external binding
99
101
This becomes incredibly useful when you need to have types that are unique to a project but shared across multiple components.
100
102
Let's say you want to create a library with a `useEnv` hook to load in environment variables found in `import.meta.env`.
101
103
```res
@@ -145,4 +147,163 @@ var Env = {
145
147
146
148
var values =import.meta.env;
147
149
```
148
-
</ CodeTab>
150
+
</ CodeTab>
151
+
152
+
## Shared functions
153
+
You might want to share functions across modules, like a way to log a value or render it in React.
154
+
Here's an example of module function that takes in a type and a transform to string function.
155
+
156
+
```res
157
+
module MakeDataModule = (
158
+
T: {
159
+
type t
160
+
let toString: t => string
161
+
},
162
+
) => {
163
+
type t = T.t
164
+
let log = a => Console.log("The value is " ++ T.toString(a))
165
+
166
+
module Render = {
167
+
@react.component
168
+
let make = (~value) => value->T.toString->React.string
169
+
}
170
+
}
171
+
```
172
+
You can now take a module with a type of `t` and a `toString` function and create a new module that has the `log` function and the `Render` component.
173
+
<CodeTablabels={["ReScript", "JS Output"]}>
174
+
```res
175
+
module Person = {
176
+
type t = { firstName: string, lastName: string }
177
+
let toString = person => person.firstName ++ person.lastName
178
+
}
179
+
180
+
module PersonData = MakeDataModule(Person)
181
+
```
182
+
183
+
```js
184
+
// Notice that none of the JS output references the MakeDataModule function
185
+
186
+
functiontoString(person) {
187
+
returnperson.firstName+person.lastName;
188
+
}
189
+
190
+
var Person = {
191
+
toString: toString
192
+
};
193
+
194
+
functionlog(a) {
195
+
console.log("The value is "+toString(a));
196
+
}
197
+
198
+
functionPerson$MakeDataModule$Render(props) {
199
+
returntoString(props.value);
200
+
}
201
+
202
+
var Render = {
203
+
make: Person$MakeDataModule$Render
204
+
};
205
+
206
+
var PersonData = {
207
+
log: log,
208
+
Render: Render
209
+
};
210
+
```
211
+
</CodeTab>
212
+
213
+
Now the `PersonData` module has the functions from the `MakeDataModule`.
214
+
<CodeTablabels={["ReScript", "JS Output"]}>
215
+
```res
216
+
@react.component
217
+
let make = (~person) => {
218
+
let handleClick = _ => PersonData.log(person)
219
+
<div>
220
+
{React.string("Hello ")}
221
+
<PersonData.Render value=person />
222
+
<button onClick=handleClick>
223
+
{React.string("Log value to console")}
224
+
</button>
225
+
</div>
226
+
}
227
+
```
228
+
```js
229
+
functionPerson$1(props) {
230
+
var person =props.person;
231
+
varhandleClick=function (param) {
232
+
log(person);
233
+
};
234
+
returnJsxRuntime.jsxs("div", {
235
+
children: [
236
+
"Hello ",
237
+
JsxRuntime.jsx(Person$MakeDataModule$Render, {
238
+
value: person
239
+
}),
240
+
JsxRuntime.jsx("button", {
241
+
children:"Log value to console",
242
+
onClick: handleClick
243
+
})
244
+
]
245
+
});
246
+
}
247
+
```
248
+
</CodeTab>
249
+
250
+
## Dependency injection
251
+
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.
0 commit comments