happy-rusty 1.4.0 → 1.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +206 -0
- package/README.cn.md +253 -26
- package/README.md +249 -28
- package/dist/main.cjs +436 -32
- package/dist/main.cjs.map +1 -1
- package/dist/main.mjs +428 -33
- package/dist/main.mjs.map +1 -1
- package/dist/types.d.ts +2070 -66
- package/package.json +37 -24
- package/dist/types.d.ts.map +0 -1
- package/docs/README.md +0 -47
- package/docs/functions/Err.md +0 -46
- package/docs/functions/Ok.md +0 -70
- package/docs/functions/Some.md +0 -45
- package/docs/functions/isOption.md +0 -35
- package/docs/functions/isResult.md +0 -36
- package/docs/functions/promiseToAsyncResult.md +0 -50
- package/docs/interfaces/None.md +0 -850
- package/docs/interfaces/Option.md +0 -761
- package/docs/interfaces/Result.md +0 -777
- package/docs/type-aliases/AsyncIOResult.md +0 -24
- package/docs/type-aliases/AsyncOption.md +0 -24
- package/docs/type-aliases/AsyncResult.md +0 -25
- package/docs/type-aliases/AsyncVoidIOResult.md +0 -17
- package/docs/type-aliases/AsyncVoidResult.md +0 -23
- package/docs/type-aliases/IOResult.md +0 -24
- package/docs/type-aliases/VoidIOResult.md +0 -17
- package/docs/type-aliases/VoidResult.md +0 -23
- package/docs/variables/None.md +0 -18
- package/docs/variables/RESULT_FALSE.md +0 -18
- package/docs/variables/RESULT_TRUE.md +0 -18
- package/docs/variables/RESULT_VOID.md +0 -17
- package/docs/variables/RESULT_ZERO.md +0 -18
- package/src/enum/constants.ts +0 -30
- package/src/enum/core.ts +0 -569
- package/src/enum/defines.ts +0 -62
- package/src/enum/extensions.ts +0 -31
- package/src/enum/mod.ts +0 -6
- package/src/enum/prelude.ts +0 -549
- package/src/enum/symbols.ts +0 -9
- package/src/enum/utils.ts +0 -27
- package/src/mod.ts +0 -1
package/dist/types.d.ts
CHANGED
|
@@ -1,9 +1,36 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* @fileoverview
|
|
3
|
+
* Internal symbols used to identify `Option` and `Result` type variants.
|
|
4
|
+
*
|
|
5
|
+
* These symbols are used as property keys to distinguish between `Some`/`None` and `Ok`/`Err` variants.
|
|
6
|
+
* They provide a reliable way to identify the variant of an `Option` or `Result` instance without
|
|
7
|
+
* relying on method calls or duck typing.
|
|
8
|
+
*
|
|
9
|
+
* Note: These symbols are internal implementation details and are not exported as part of the public API.
|
|
10
|
+
* Use the `isOption` and `isResult` utility functions for type checking instead.
|
|
11
|
+
*/
|
|
12
|
+
/**
|
|
13
|
+
* A unique symbol used as a property key to identify the variant of an `Option` instance.
|
|
14
|
+
*
|
|
15
|
+
* When accessed on an `Option`, returns `'Some'` if the Option contains a value,
|
|
16
|
+
* or `'None'` if it represents the absence of a value.
|
|
17
|
+
*
|
|
18
|
+
* This symbol is used internally by the `isOption` utility function to verify
|
|
19
|
+
* that an object is a valid `Option` instance.
|
|
20
|
+
*
|
|
21
|
+
* @internal
|
|
3
22
|
*/
|
|
4
23
|
declare const OptionKindSymbol: unique symbol;
|
|
5
24
|
/**
|
|
6
|
-
*
|
|
25
|
+
* A unique symbol used as a property key to identify the variant of a `Result` instance.
|
|
26
|
+
*
|
|
27
|
+
* When accessed on a `Result`, returns `'Ok'` if the Result represents success,
|
|
28
|
+
* or `'Err'` if it represents failure.
|
|
29
|
+
*
|
|
30
|
+
* This symbol is used internally by the `isResult` utility function to verify
|
|
31
|
+
* that an object is a valid `Result` instance.
|
|
32
|
+
*
|
|
33
|
+
* @internal
|
|
7
34
|
*/
|
|
8
35
|
declare const ResultKindSymbol: unique symbol;
|
|
9
36
|
|
|
@@ -30,13 +57,31 @@ pub enum Option<T> {
|
|
|
30
57
|
*/
|
|
31
58
|
interface Option<T> {
|
|
32
59
|
/**
|
|
33
|
-
*
|
|
60
|
+
* The well-known symbol `Symbol.toStringTag` used by `Object.prototype.toString()`.
|
|
61
|
+
* Returns `'Option'` so that `Object.prototype.toString.call(option)` produces `'[object Option]'`.
|
|
62
|
+
*
|
|
63
|
+
* This enables reliable type identification even across different execution contexts (e.g., iframes, different module instances).
|
|
64
|
+
*
|
|
65
|
+
* @example
|
|
66
|
+
* ```ts
|
|
67
|
+
* const x = Some(5);
|
|
68
|
+
* console.log(Object.prototype.toString.call(x)); // '[object Option]'
|
|
69
|
+
* ```
|
|
70
|
+
*
|
|
71
|
+
* @internal
|
|
34
72
|
*/
|
|
35
|
-
[Symbol.toStringTag]: 'Option';
|
|
73
|
+
readonly [Symbol.toStringTag]: 'Option';
|
|
36
74
|
/**
|
|
37
|
-
*
|
|
75
|
+
* A unique symbol property used to identify the variant of this `Option`.
|
|
76
|
+
* Returns `'Some'` if the Option contains a value, or `'None'` if it represents absence.
|
|
77
|
+
*
|
|
78
|
+
* This is used internally by the `isOption` utility function to verify that an object is a valid `Option` instance,
|
|
79
|
+
* and to distinguish between `Some` and `None` variants without calling methods.
|
|
80
|
+
*
|
|
81
|
+
* Note: The symbol itself is not exported as part of the public API.
|
|
82
|
+
* Use the `isOption` utility function or the `isSome()`/`isNone()` methods for type checking.
|
|
38
83
|
*
|
|
39
|
-
* @
|
|
84
|
+
* @internal
|
|
40
85
|
*/
|
|
41
86
|
readonly [OptionKindSymbol]: 'Some' | 'None';
|
|
42
87
|
/**
|
|
@@ -44,17 +89,81 @@ interface Option<T> {
|
|
|
44
89
|
*/
|
|
45
90
|
/**
|
|
46
91
|
* Returns `true` if the Option is a `Some` value.
|
|
92
|
+
* @example
|
|
93
|
+
* ```ts
|
|
94
|
+
* const x = Some(2);
|
|
95
|
+
* console.log(x.isSome()); // true
|
|
96
|
+
*
|
|
97
|
+
* const y = None;
|
|
98
|
+
* console.log(y.isSome()); // false
|
|
99
|
+
* ```
|
|
47
100
|
*/
|
|
48
101
|
isSome(): boolean;
|
|
49
102
|
/**
|
|
50
103
|
* Returns `true` if the Option is a `None` value.
|
|
104
|
+
* @example
|
|
105
|
+
* ```ts
|
|
106
|
+
* const x = Some(2);
|
|
107
|
+
* console.log(x.isNone()); // false
|
|
108
|
+
*
|
|
109
|
+
* const y = None;
|
|
110
|
+
* console.log(y.isNone()); // true
|
|
111
|
+
* ```
|
|
51
112
|
*/
|
|
52
113
|
isNone(): boolean;
|
|
53
114
|
/**
|
|
54
115
|
* Returns `true` if the Option is a `Some` value and the predicate returns `true` for the contained value.
|
|
55
116
|
* @param predicate - A function that takes the contained value and returns a boolean.
|
|
117
|
+
* @example
|
|
118
|
+
* ```ts
|
|
119
|
+
* const x = Some(2);
|
|
120
|
+
* console.log(x.isSomeAnd(v => v > 1)); // true
|
|
121
|
+
* console.log(x.isSomeAnd(v => v > 5)); // false
|
|
122
|
+
* ```
|
|
56
123
|
*/
|
|
57
124
|
isSomeAnd(predicate: (value: T) => boolean): boolean;
|
|
125
|
+
/**
|
|
126
|
+
* Asynchronous version of `isSomeAnd`.
|
|
127
|
+
* @param predicate - An async function that takes the contained value and returns a `Promise<boolean>`.
|
|
128
|
+
* @returns A promise that resolves to `true` if the Option is `Some` and the predicate resolves to `true`.
|
|
129
|
+
* @see isSomeAnd
|
|
130
|
+
* @example
|
|
131
|
+
* ```ts
|
|
132
|
+
* const x = Some(2);
|
|
133
|
+
* await x.isSomeAndAsync(async v => v > 1); // true
|
|
134
|
+
* ```
|
|
135
|
+
*/
|
|
136
|
+
isSomeAndAsync(predicate: (value: T) => Promise<boolean>): Promise<boolean>;
|
|
137
|
+
/**
|
|
138
|
+
* Returns `true` if the Option is `None`, or the predicate returns `true` for the contained value.
|
|
139
|
+
* @param predicate - A function that takes the contained value and returns a boolean.
|
|
140
|
+
* @see isSomeAnd
|
|
141
|
+
* @example
|
|
142
|
+
* ```ts
|
|
143
|
+
* const x = Some(2);
|
|
144
|
+
* console.log(x.isNoneOr(v => v > 1)); // true
|
|
145
|
+
* console.log(x.isNoneOr(v => v > 5)); // false
|
|
146
|
+
*
|
|
147
|
+
* const y = None;
|
|
148
|
+
* console.log(y.isNoneOr(v => v > 5)); // true (always true for None)
|
|
149
|
+
* ```
|
|
150
|
+
*/
|
|
151
|
+
isNoneOr(predicate: (value: T) => boolean): boolean;
|
|
152
|
+
/**
|
|
153
|
+
* Asynchronous version of `isNoneOr`.
|
|
154
|
+
* @param predicate - An async function that takes the contained value and returns a `Promise<boolean>`.
|
|
155
|
+
* @returns A promise that resolves to `true` if the Option is `None` or the predicate resolves to `true`.
|
|
156
|
+
* @see isNoneOr
|
|
157
|
+
* @example
|
|
158
|
+
* ```ts
|
|
159
|
+
* const x = Some(2);
|
|
160
|
+
* await x.isNoneOrAsync(async v => v > 1); // true
|
|
161
|
+
*
|
|
162
|
+
* const y = None;
|
|
163
|
+
* await y.isNoneOrAsync(async v => v > 5); // true
|
|
164
|
+
* ```
|
|
165
|
+
*/
|
|
166
|
+
isNoneOrAsync(predicate: (value: T) => Promise<boolean>): Promise<boolean>;
|
|
58
167
|
/**
|
|
59
168
|
* These methods extract the contained value in an `Option<T>` when it is the `Some` variant:
|
|
60
169
|
*/
|
|
@@ -62,23 +171,69 @@ interface Option<T> {
|
|
|
62
171
|
* Returns the contained `Some` value, with a provided error message if the value is a `None`.
|
|
63
172
|
* @param msg - The error message to provide if the value is a `None`.
|
|
64
173
|
* @throws {TypeError} Throws an error with the provided message if the Option is a `None`.
|
|
174
|
+
* @see unwrap
|
|
175
|
+
* @example
|
|
176
|
+
* ```ts
|
|
177
|
+
* const x = Some(5);
|
|
178
|
+
* console.log(x.expect('value should exist')); // 5
|
|
179
|
+
*
|
|
180
|
+
* const y = None;
|
|
181
|
+
* y.expect('value should exist'); // throws TypeError: value should exist
|
|
182
|
+
* ```
|
|
65
183
|
*/
|
|
66
184
|
expect(msg: string): T;
|
|
67
185
|
/**
|
|
68
186
|
* Returns the contained `Some` value.
|
|
69
187
|
* @throws {TypeError} Throws an error if the value is a `None`.
|
|
188
|
+
* @see expect
|
|
189
|
+
* @see unwrapOr
|
|
190
|
+
* @example
|
|
191
|
+
* ```ts
|
|
192
|
+
* const x = Some(5);
|
|
193
|
+
* console.log(x.unwrap()); // 5
|
|
194
|
+
*
|
|
195
|
+
* const y = None;
|
|
196
|
+
* y.unwrap(); // throws TypeError
|
|
197
|
+
* ```
|
|
70
198
|
*/
|
|
71
199
|
unwrap(): T;
|
|
72
200
|
/**
|
|
73
201
|
* Returns the contained `Some` value or a provided default.
|
|
74
202
|
* @param defaultValue - The value to return if the Option is a `None`.
|
|
203
|
+
* @see unwrapOrElse
|
|
204
|
+
* @example
|
|
205
|
+
* ```ts
|
|
206
|
+
* const x = Some(5);
|
|
207
|
+
* console.log(x.unwrapOr(10)); // 5
|
|
208
|
+
*
|
|
209
|
+
* const y = None;
|
|
210
|
+
* console.log(y.unwrapOr(10)); // 10
|
|
211
|
+
* ```
|
|
75
212
|
*/
|
|
76
213
|
unwrapOr(defaultValue: T): T;
|
|
77
214
|
/**
|
|
78
215
|
* Returns the contained `Some` value or computes it from a closure.
|
|
79
216
|
* @param fn - A function that returns the default value.
|
|
217
|
+
* @see unwrapOr
|
|
218
|
+
* @example
|
|
219
|
+
* ```ts
|
|
220
|
+
* const x = None;
|
|
221
|
+
* console.log(x.unwrapOrElse(() => 10)); // 10
|
|
222
|
+
* ```
|
|
80
223
|
*/
|
|
81
224
|
unwrapOrElse(fn: () => T): T;
|
|
225
|
+
/**
|
|
226
|
+
* Asynchronous version of `unwrapOrElse`.
|
|
227
|
+
* @param fn - An async function that returns a `Promise<T>` as the default value.
|
|
228
|
+
* @returns A promise that resolves to the contained value or the result of the async function.
|
|
229
|
+
* @see unwrapOrElse
|
|
230
|
+
* @example
|
|
231
|
+
* ```ts
|
|
232
|
+
* const x = None;
|
|
233
|
+
* await x.unwrapOrElseAsync(async () => 10); // 10
|
|
234
|
+
* ```
|
|
235
|
+
*/
|
|
236
|
+
unwrapOrElseAsync(fn: () => Promise<T>): Promise<T>;
|
|
82
237
|
/**
|
|
83
238
|
* These methods transform `Option` to `Result`:
|
|
84
239
|
*/
|
|
@@ -86,23 +241,49 @@ interface Option<T> {
|
|
|
86
241
|
* Transforms the `Option<T>` into a `Result<T, E>`, mapping `Some(v)` to `Ok(v)` and `None` to `Err(err)`.
|
|
87
242
|
* @typeParam E - The type of the error value in the `Err` variant of the resulting `Result`.
|
|
88
243
|
* @param error - The error value to use if the Option is a `None`.
|
|
244
|
+
* @see okOrElse
|
|
245
|
+
* @example
|
|
246
|
+
* ```ts
|
|
247
|
+
* const x = Some(5);
|
|
248
|
+
* console.log(x.okOr('error').isOk()); // true
|
|
249
|
+
*
|
|
250
|
+
* const y = None;
|
|
251
|
+
* console.log(y.okOr('error').unwrapErr()); // 'error'
|
|
252
|
+
* ```
|
|
89
253
|
*/
|
|
90
254
|
okOr<E>(error: E): Result<T, E>;
|
|
91
255
|
/**
|
|
92
256
|
* Transforms the `Option<T>` into a `Result<T, E>`, mapping `Some(v)` to `Ok(v)` and `None` to `Err(err())`.
|
|
93
257
|
* @typeParam E - The type of the error value in the `Err` variant of the resulting `Result`.
|
|
94
258
|
* @param err - A function that returns the error value.
|
|
259
|
+
* @see okOr
|
|
260
|
+
* @example
|
|
261
|
+
* ```ts
|
|
262
|
+
* const x = None;
|
|
263
|
+
* console.log(x.okOrElse(() => 'error').unwrapErr()); // 'error'
|
|
264
|
+
* ```
|
|
95
265
|
*/
|
|
96
266
|
okOrElse<E>(err: () => E): Result<T, E>;
|
|
97
267
|
/**
|
|
98
268
|
* Transposes an `Option` of a `Result` into a `Result` of an `Option`.
|
|
99
|
-
* @typeParam
|
|
269
|
+
* @typeParam U - The type of the success value in the `Ok` variant of the `Result`.
|
|
100
270
|
* @typeParam E - The type of the error value in the `Err` variant of the `Result`.
|
|
101
271
|
* @returns `Ok` containing `Some` if the Option is a `Some` containing `Ok`,
|
|
102
272
|
* `Err` containing the error if the Option is a `Some` containing `Err`,
|
|
103
273
|
* `Ok` containing `None` if the Option is `None`.
|
|
274
|
+
* @example
|
|
275
|
+
* ```ts
|
|
276
|
+
* const x = Some(Ok(5));
|
|
277
|
+
* console.log(x.transpose().unwrap().unwrap()); // 5
|
|
278
|
+
*
|
|
279
|
+
* const y = Some(Err('error'));
|
|
280
|
+
* console.log(y.transpose().unwrapErr()); // 'error'
|
|
281
|
+
*
|
|
282
|
+
* const z: Option<Result<number, string>> = None;
|
|
283
|
+
* console.log(z.transpose().unwrap().isNone()); // true
|
|
284
|
+
* ```
|
|
104
285
|
*/
|
|
105
|
-
transpose<
|
|
286
|
+
transpose<U, E>(this: Option<Result<U, E>>): Result<Option<U>, E>;
|
|
106
287
|
/**
|
|
107
288
|
* These methods transform the `Some` variant:
|
|
108
289
|
*/
|
|
@@ -111,17 +292,41 @@ interface Option<T> {
|
|
|
111
292
|
* - `Some(t)` if predicate returns `true` (where `t` is the wrapped value), and
|
|
112
293
|
* - `None` if predicate returns `false`.
|
|
113
294
|
* @param predicate - A function that takes the contained value and returns a boolean.
|
|
295
|
+
* @example
|
|
296
|
+
* ```ts
|
|
297
|
+
* const x = Some(4);
|
|
298
|
+
* console.log(x.filter(v => v > 2).isSome()); // true
|
|
299
|
+
* console.log(x.filter(v => v > 5).isNone()); // true
|
|
300
|
+
* ```
|
|
114
301
|
*/
|
|
115
302
|
filter(predicate: (value: T) => boolean): Option<T>;
|
|
116
303
|
/**
|
|
117
|
-
* Converts from `Option<Option<
|
|
304
|
+
* Converts from `Option<Option<U>>` to `Option<U>`.
|
|
305
|
+
* @typeParam U - The type of the value contained in the inner `Option`.
|
|
118
306
|
* @returns `None` if the Option is `None`, otherwise returns the contained `Option`.
|
|
307
|
+
* @example
|
|
308
|
+
* ```ts
|
|
309
|
+
* const x = Some(Some(5));
|
|
310
|
+
* console.log(x.flatten().unwrap()); // 5
|
|
311
|
+
*
|
|
312
|
+
* const y = Some(None);
|
|
313
|
+
* console.log(y.flatten().isNone()); // true
|
|
314
|
+
* ```
|
|
119
315
|
*/
|
|
120
|
-
flatten<
|
|
316
|
+
flatten<U>(this: Option<Option<U>>): Option<U>;
|
|
121
317
|
/**
|
|
122
318
|
* Maps an `Option<T>` to `Option<U>` by applying a function to a contained value.
|
|
123
319
|
* @typeParam U - The type of the value returned by the map function.
|
|
124
320
|
* @param fn - A function that takes the contained value and returns a new value.
|
|
321
|
+
* @see andThen
|
|
322
|
+
* @example
|
|
323
|
+
* ```ts
|
|
324
|
+
* const x = Some(5);
|
|
325
|
+
* console.log(x.map(v => v * 2).unwrap()); // 10
|
|
326
|
+
*
|
|
327
|
+
* const y = None;
|
|
328
|
+
* console.log(y.map(v => v * 2).isNone()); // true
|
|
329
|
+
* ```
|
|
125
330
|
*/
|
|
126
331
|
map<U>(fn: (value: T) => U): Option<U>;
|
|
127
332
|
/**
|
|
@@ -129,6 +334,15 @@ interface Option<T> {
|
|
|
129
334
|
* @typeParam U - The type of the value returned by the map function or the default value.
|
|
130
335
|
* @param defaultValue - The value to return if the Option is `None`.
|
|
131
336
|
* @param fn - A function that takes the contained value and returns a new value.
|
|
337
|
+
* @see mapOrElse
|
|
338
|
+
* @example
|
|
339
|
+
* ```ts
|
|
340
|
+
* const x = Some(5);
|
|
341
|
+
* console.log(x.mapOr(0, v => v * 2)); // 10
|
|
342
|
+
*
|
|
343
|
+
* const y = None;
|
|
344
|
+
* console.log(y.mapOr(0, v => v * 2)); // 0
|
|
345
|
+
* ```
|
|
132
346
|
*/
|
|
133
347
|
mapOr<U>(defaultValue: U, fn: (value: T) => U): U;
|
|
134
348
|
/**
|
|
@@ -136,6 +350,15 @@ interface Option<T> {
|
|
|
136
350
|
* @typeParam U - The type of the value returned by the map function or the default function.
|
|
137
351
|
* @param defaultFn - A function that returns the default value.
|
|
138
352
|
* @param fn - A function that takes the contained value and returns a new value.
|
|
353
|
+
* @see mapOr
|
|
354
|
+
* @example
|
|
355
|
+
* ```ts
|
|
356
|
+
* const x = Some(5);
|
|
357
|
+
* console.log(x.mapOrElse(() => 0, v => v * 2)); // 10
|
|
358
|
+
*
|
|
359
|
+
* const y = None;
|
|
360
|
+
* console.log(y.mapOrElse(() => 0, v => v * 2)); // 0
|
|
361
|
+
* ```
|
|
139
362
|
*/
|
|
140
363
|
mapOrElse<U>(defaultFn: () => U, fn: (value: T) => U): U;
|
|
141
364
|
/**
|
|
@@ -148,6 +371,17 @@ interface Option<T> {
|
|
|
148
371
|
* @typeParam U - The type of the value in the other `Option`.
|
|
149
372
|
* @param other - The other `Option` to zip with.
|
|
150
373
|
* @returns An `Option` containing a tuple of the values if both are `Some`, otherwise `None`.
|
|
374
|
+
* @see zipWith
|
|
375
|
+
* @see unzip
|
|
376
|
+
* @example
|
|
377
|
+
* ```ts
|
|
378
|
+
* const x = Some(1);
|
|
379
|
+
* const y = Some('hello');
|
|
380
|
+
* console.log(x.zip(y).unwrap()); // [1, 'hello']
|
|
381
|
+
*
|
|
382
|
+
* const z = None;
|
|
383
|
+
* console.log(x.zip(z).isNone()); // true
|
|
384
|
+
* ```
|
|
151
385
|
*/
|
|
152
386
|
zip<U>(other: Option<U>): Option<[T, U]>;
|
|
153
387
|
/**
|
|
@@ -159,17 +393,32 @@ interface Option<T> {
|
|
|
159
393
|
* @param other - The other `Option` to zip with.
|
|
160
394
|
* @param fn - The function to combine the values from both `Options`.
|
|
161
395
|
* @returns An `Option` containing the result of `fn` if both `Options` are `Some`, otherwise `None`.
|
|
396
|
+
* @see zip
|
|
397
|
+
* @example
|
|
398
|
+
* ```ts
|
|
399
|
+
* const x = Some(2);
|
|
400
|
+
* const y = Some(3);
|
|
401
|
+
* console.log(x.zipWith(y, (a, b) => a * b).unwrap()); // 6
|
|
402
|
+
* ```
|
|
162
403
|
*/
|
|
163
404
|
zipWith<U, R>(other: Option<U>, fn: (value: T, otherValue: U) => R): Option<R>;
|
|
164
405
|
/**
|
|
165
|
-
* Converts from `Option<[
|
|
406
|
+
* Converts from `Option<[U, R]>` to `[Option<U>, Option<R>]`.
|
|
166
407
|
* If `this` is `Some([a, b])`, returns `[Some(a), Some(b)]`.
|
|
167
408
|
* If `this` is `None`, returns `[None, None]`.
|
|
168
|
-
* @typeParam
|
|
169
|
-
* @typeParam
|
|
409
|
+
* @typeParam U - The type of the first value in the tuple.
|
|
410
|
+
* @typeParam R - The type of the second value in the tuple.
|
|
170
411
|
* @returns A tuple of `Options`, one for each element in the original `Option` of a tuple.
|
|
412
|
+
* @see zip
|
|
413
|
+
* @example
|
|
414
|
+
* ```ts
|
|
415
|
+
* const x = Some([1, 'hello'] as [number, string]);
|
|
416
|
+
* const [a, b] = x.unzip();
|
|
417
|
+
* console.log(a.unwrap()); // 1
|
|
418
|
+
* console.log(b.unwrap()); // 'hello'
|
|
419
|
+
* ```
|
|
171
420
|
*/
|
|
172
|
-
unzip<
|
|
421
|
+
unzip<U, R>(this: Option<[U, R]>): [Option<U>, Option<R>];
|
|
173
422
|
/**
|
|
174
423
|
* These methods treat the `Option` as a boolean value, where `Some` acts like `true` and `None` acts like `false`.
|
|
175
424
|
*/
|
|
@@ -179,6 +428,17 @@ interface Option<T> {
|
|
|
179
428
|
* @typeParam U - The type of the value in the other `Option`.
|
|
180
429
|
* @param other - The `Option` to return if `this` is `Some`.
|
|
181
430
|
* @returns `None` if `this` is `None`, otherwise returns `other`.
|
|
431
|
+
* @see or
|
|
432
|
+
* @see xor
|
|
433
|
+
* @example
|
|
434
|
+
* ```ts
|
|
435
|
+
* const x = Some(2);
|
|
436
|
+
* const y = Some('hello');
|
|
437
|
+
* console.log(x.and(y).unwrap()); // 'hello'
|
|
438
|
+
*
|
|
439
|
+
* const z = None;
|
|
440
|
+
* console.log(z.and(y).isNone()); // true
|
|
441
|
+
* ```
|
|
182
442
|
*/
|
|
183
443
|
and<U>(other: Option<U>): Option<U>;
|
|
184
444
|
/**
|
|
@@ -187,13 +447,50 @@ interface Option<T> {
|
|
|
187
447
|
* @typeParam U - The type of the value returned by the function.
|
|
188
448
|
* @param fn - A function that takes the contained value and returns an `Option`.
|
|
189
449
|
* @returns The result of `fn` if `this` is `Some`, otherwise `None`.
|
|
450
|
+
* @see map
|
|
451
|
+
* @see orElse
|
|
452
|
+
* @example
|
|
453
|
+
* ```ts
|
|
454
|
+
* const x = Some(2);
|
|
455
|
+
* const result = x.andThen(v => v > 0 ? Some(v * 2) : None);
|
|
456
|
+
* console.log(result.unwrap()); // 4
|
|
457
|
+
*
|
|
458
|
+
* const y = None;
|
|
459
|
+
* console.log(y.andThen(v => Some(v * 2)).isNone()); // true
|
|
460
|
+
* ```
|
|
190
461
|
*/
|
|
191
462
|
andThen<U>(fn: (value: T) => Option<U>): Option<U>;
|
|
463
|
+
/**
|
|
464
|
+
* Asynchronous version of `andThen`.
|
|
465
|
+
* @typeParam U - The type of the value returned by the async function.
|
|
466
|
+
* @param fn - An async function that takes the contained value and returns a `Promise<Option<U>>`.
|
|
467
|
+
* @returns A promise that resolves to `None` if `this` is `None`, otherwise the result of `fn`.
|
|
468
|
+
* @see andThen
|
|
469
|
+
* @see orElseAsync
|
|
470
|
+
* @example
|
|
471
|
+
* ```ts
|
|
472
|
+
* const x = Some(2);
|
|
473
|
+
* const result = await x.andThenAsync(async v => Some(v * 2));
|
|
474
|
+
* console.log(result.unwrap()); // 4
|
|
475
|
+
* ```
|
|
476
|
+
*/
|
|
477
|
+
andThenAsync<U>(fn: (value: T) => AsyncOption<U>): AsyncOption<U>;
|
|
192
478
|
/**
|
|
193
479
|
* Returns the Option if it contains a value, otherwise returns `other`.
|
|
194
480
|
* This can be used for providing a fallback `Option`.
|
|
195
481
|
* @param other - The fallback `Option` to use if `this` is `None`.
|
|
196
482
|
* @returns `this` if it is `Some`, otherwise `other`.
|
|
483
|
+
* @see and
|
|
484
|
+
* @see xor
|
|
485
|
+
* @example
|
|
486
|
+
* ```ts
|
|
487
|
+
* const x = None;
|
|
488
|
+
* const y = Some(5);
|
|
489
|
+
* console.log(x.or(y).unwrap()); // 5
|
|
490
|
+
*
|
|
491
|
+
* const z = Some(2);
|
|
492
|
+
* console.log(z.or(y).unwrap()); // 2
|
|
493
|
+
* ```
|
|
197
494
|
*/
|
|
198
495
|
or(other: Option<T>): Option<T>;
|
|
199
496
|
/**
|
|
@@ -201,13 +498,49 @@ interface Option<T> {
|
|
|
201
498
|
* This method can be used for lazy fallbacks, as `fn` is only evaluated if `this` is `None`.
|
|
202
499
|
* @param fn - A function that produces an `Option`.
|
|
203
500
|
* @returns `this` if it is `Some`, otherwise the result of `fn`.
|
|
501
|
+
* @see andThen
|
|
502
|
+
* @example
|
|
503
|
+
* ```ts
|
|
504
|
+
* const x = None;
|
|
505
|
+
* const result = x.orElse(() => Some(10));
|
|
506
|
+
* console.log(result.unwrap()); // 10
|
|
507
|
+
*
|
|
508
|
+
* const y = Some(5);
|
|
509
|
+
* console.log(y.orElse(() => Some(10)).unwrap()); // 5
|
|
510
|
+
* ```
|
|
204
511
|
*/
|
|
205
512
|
orElse(fn: () => Option<T>): Option<T>;
|
|
513
|
+
/**
|
|
514
|
+
* Asynchronous version of `orElse`.
|
|
515
|
+
* @param fn - An async function that produces a `Promise<Option<T>>`.
|
|
516
|
+
* @returns A promise that resolves to `this` if it is `Some`, otherwise the result of `fn`.
|
|
517
|
+
* @see orElse
|
|
518
|
+
* @see andThenAsync
|
|
519
|
+
* @example
|
|
520
|
+
* ```ts
|
|
521
|
+
* const x = None;
|
|
522
|
+
* const result = await x.orElseAsync(async () => Some(10));
|
|
523
|
+
* console.log(result.unwrap()); // 10
|
|
524
|
+
* ```
|
|
525
|
+
*/
|
|
526
|
+
orElseAsync(fn: () => AsyncOption<T>): AsyncOption<T>;
|
|
206
527
|
/**
|
|
207
528
|
* Returns `Some` if exactly one of `this`, `other` is `Some`, otherwise returns `None`.
|
|
208
529
|
* This can be thought of as an exclusive or operation on `Option` values.
|
|
209
530
|
* @param other - The other `Option` to compare with.
|
|
210
531
|
* @returns `Some` if exactly one of `this` and `other` is `Some`, otherwise `None`.
|
|
532
|
+
* @see and
|
|
533
|
+
* @see or
|
|
534
|
+
* @example
|
|
535
|
+
* ```ts
|
|
536
|
+
* const x = Some(2);
|
|
537
|
+
* const y = None;
|
|
538
|
+
* console.log(x.xor(y).unwrap()); // 2
|
|
539
|
+
*
|
|
540
|
+
* const a = Some(2);
|
|
541
|
+
* const b = Some(3);
|
|
542
|
+
* console.log(a.xor(b).isNone()); // true
|
|
543
|
+
* ```
|
|
211
544
|
*/
|
|
212
545
|
xor(other: Option<T>): Option<T>;
|
|
213
546
|
/**
|
|
@@ -215,6 +548,16 @@ interface Option<T> {
|
|
|
215
548
|
* This is primarily for side effects and does not transform the `Option`.
|
|
216
549
|
* @param fn - A function to call with the contained value.
|
|
217
550
|
* @returns `this`, unmodified, for chaining additional methods.
|
|
551
|
+
* @example
|
|
552
|
+
* ```ts
|
|
553
|
+
* const x = Some(5);
|
|
554
|
+
* // Prints "value: 5" and returns Some(10)
|
|
555
|
+
* const doubled = x.inspect(v => console.log('value:', v)).map(v => v * 2);
|
|
556
|
+
*
|
|
557
|
+
* const y = None;
|
|
558
|
+
* // Does nothing and returns None
|
|
559
|
+
* y.inspect(v => console.log('value:', v));
|
|
560
|
+
* ```
|
|
218
561
|
*/
|
|
219
562
|
inspect(fn: (value: T) => void): this;
|
|
220
563
|
/**
|
|
@@ -222,10 +565,25 @@ interface Option<T> {
|
|
|
222
565
|
* This method can be used for comparing `Option` instances in a value-sensitive manner.
|
|
223
566
|
* @param other - The other `Option` to compare with.
|
|
224
567
|
* @returns `true` if `this` and `other` are both `Some` with equal values, or both are `None`, otherwise `false`.
|
|
568
|
+
* @example
|
|
569
|
+
* ```ts
|
|
570
|
+
* const a = Some(5);
|
|
571
|
+
* const b = Some(5);
|
|
572
|
+
* const c = Some(10);
|
|
573
|
+
* console.log(a.eq(b)); // true
|
|
574
|
+
* console.log(a.eq(c)); // false
|
|
575
|
+
* console.log(None.eq(None)); // true
|
|
576
|
+
* console.log(a.eq(None)); // false
|
|
577
|
+
* ```
|
|
225
578
|
*/
|
|
226
579
|
eq(other: Option<T>): boolean;
|
|
227
580
|
/**
|
|
228
581
|
* Custom `toString` implementation that uses the `Option`'s contained value.
|
|
582
|
+
* @example
|
|
583
|
+
* ```ts
|
|
584
|
+
* console.log(Some(5).toString()); // 'Some(5)'
|
|
585
|
+
* console.log(None.toString()); // 'None'
|
|
586
|
+
* ```
|
|
229
587
|
*/
|
|
230
588
|
toString(): string;
|
|
231
589
|
}
|
|
@@ -246,13 +604,31 @@ pub enum Result<T, E> {
|
|
|
246
604
|
*/
|
|
247
605
|
interface Result<T, E> {
|
|
248
606
|
/**
|
|
249
|
-
*
|
|
607
|
+
* The well-known symbol `Symbol.toStringTag` used by `Object.prototype.toString()`.
|
|
608
|
+
* Returns `'Result'` so that `Object.prototype.toString.call(result)` produces `'[object Result]'`.
|
|
609
|
+
*
|
|
610
|
+
* This enables reliable type identification even across different execution contexts (e.g., iframes, different module instances).
|
|
611
|
+
*
|
|
612
|
+
* @example
|
|
613
|
+
* ```ts
|
|
614
|
+
* const x = Ok(5);
|
|
615
|
+
* console.log(Object.prototype.toString.call(x)); // '[object Result]'
|
|
616
|
+
* ```
|
|
617
|
+
*
|
|
618
|
+
* @internal
|
|
250
619
|
*/
|
|
251
|
-
[Symbol.toStringTag]: 'Result';
|
|
620
|
+
readonly [Symbol.toStringTag]: 'Result';
|
|
252
621
|
/**
|
|
253
|
-
*
|
|
622
|
+
* A unique symbol property used to identify the variant of this `Result`.
|
|
623
|
+
* Returns `'Ok'` if the Result represents success, or `'Err'` if it represents failure.
|
|
624
|
+
*
|
|
625
|
+
* This is used internally by the `isResult` utility function to verify that an object is a valid `Result` instance,
|
|
626
|
+
* and to distinguish between `Ok` and `Err` variants without calling methods.
|
|
627
|
+
*
|
|
628
|
+
* Note: The symbol itself is not exported as part of the public API.
|
|
629
|
+
* Use the `isResult` utility function or the `isOk()`/`isErr()` methods for type checking.
|
|
254
630
|
*
|
|
255
|
-
* @
|
|
631
|
+
* @internal
|
|
256
632
|
*/
|
|
257
633
|
readonly [ResultKindSymbol]: 'Ok' | 'Err';
|
|
258
634
|
/**
|
|
@@ -260,22 +636,77 @@ interface Result<T, E> {
|
|
|
260
636
|
*/
|
|
261
637
|
/**
|
|
262
638
|
* Returns `true` if the result is `Ok`.
|
|
639
|
+
* @example
|
|
640
|
+
* ```ts
|
|
641
|
+
* const x = Ok(5);
|
|
642
|
+
* console.log(x.isOk()); // true
|
|
643
|
+
*
|
|
644
|
+
* const y = Err('error');
|
|
645
|
+
* console.log(y.isOk()); // false
|
|
646
|
+
* ```
|
|
263
647
|
*/
|
|
264
648
|
isOk(): boolean;
|
|
265
649
|
/**
|
|
266
650
|
* Returns `true` if the result is `Err`.
|
|
651
|
+
* @example
|
|
652
|
+
* ```ts
|
|
653
|
+
* const x = Ok(5);
|
|
654
|
+
* console.log(x.isErr()); // false
|
|
655
|
+
*
|
|
656
|
+
* const y = Err('error');
|
|
657
|
+
* console.log(y.isErr()); // true
|
|
658
|
+
* ```
|
|
267
659
|
*/
|
|
268
660
|
isErr(): boolean;
|
|
269
661
|
/**
|
|
270
662
|
* Returns `true` if the result is `Ok` and the provided predicate returns `true` for the contained value.
|
|
271
663
|
* @param predicate - A function that takes the `Ok` value and returns a boolean.
|
|
664
|
+
* @see isErrAnd
|
|
665
|
+
* @example
|
|
666
|
+
* ```ts
|
|
667
|
+
* const x = Ok(2);
|
|
668
|
+
* console.log(x.isOkAnd(v => v > 1)); // true
|
|
669
|
+
* console.log(x.isOkAnd(v => v > 5)); // false
|
|
670
|
+
* ```
|
|
272
671
|
*/
|
|
273
672
|
isOkAnd(predicate: (value: T) => boolean): boolean;
|
|
673
|
+
/**
|
|
674
|
+
* Asynchronous version of `isOkAnd`.
|
|
675
|
+
* @param predicate - An async function that takes the `Ok` value and returns a `Promise<boolean>`.
|
|
676
|
+
* @returns A promise that resolves to `true` if the Result is `Ok` and the predicate resolves to `true`.
|
|
677
|
+
* @see isOkAnd
|
|
678
|
+
* @see isErrAndAsync
|
|
679
|
+
* @example
|
|
680
|
+
* ```ts
|
|
681
|
+
* const x = Ok(2);
|
|
682
|
+
* await x.isOkAndAsync(async v => v > 1); // true
|
|
683
|
+
* ```
|
|
684
|
+
*/
|
|
685
|
+
isOkAndAsync(predicate: (value: T) => Promise<boolean>): Promise<boolean>;
|
|
274
686
|
/**
|
|
275
687
|
* Returns `true` if the result is `Err` and the provided predicate returns `true` for the contained error.
|
|
276
688
|
* @param predicate - A function that takes the `Err` value and returns a boolean.
|
|
689
|
+
* @see isOkAnd
|
|
690
|
+
* @example
|
|
691
|
+
* ```ts
|
|
692
|
+
* const x = Err('error');
|
|
693
|
+
* console.log(x.isErrAnd(e => e === 'error')); // true
|
|
694
|
+
* ```
|
|
277
695
|
*/
|
|
278
696
|
isErrAnd(predicate: (error: E) => boolean): boolean;
|
|
697
|
+
/**
|
|
698
|
+
* Asynchronous version of `isErrAnd`.
|
|
699
|
+
* @param predicate - An async function that takes the `Err` value and returns a `Promise<boolean>`.
|
|
700
|
+
* @returns A promise that resolves to `true` if the Result is `Err` and the predicate resolves to `true`.
|
|
701
|
+
* @see isErrAnd
|
|
702
|
+
* @see isOkAndAsync
|
|
703
|
+
* @example
|
|
704
|
+
* ```ts
|
|
705
|
+
* const x = Err('error');
|
|
706
|
+
* await x.isErrAndAsync(async e => e.length > 0); // true
|
|
707
|
+
* ```
|
|
708
|
+
*/
|
|
709
|
+
isErrAndAsync(predicate: (error: E) => Promise<boolean>): Promise<boolean>;
|
|
279
710
|
/**
|
|
280
711
|
* These methods extract the contained value in a `Result<T, E>` when it is the `Ok` variant.
|
|
281
712
|
*/
|
|
@@ -283,23 +714,71 @@ interface Result<T, E> {
|
|
|
283
714
|
* Returns the contained `Ok` value, with a provided error message if the result is `Err`.
|
|
284
715
|
* @param msg - The error message to provide if the result is an `Err`.
|
|
285
716
|
* @throws {TypeError} Throws an error with the provided message if the result is an `Err`.
|
|
717
|
+
* @see unwrap
|
|
718
|
+
* @see expectErr
|
|
719
|
+
* @example
|
|
720
|
+
* ```ts
|
|
721
|
+
* const x = Ok(5);
|
|
722
|
+
* console.log(x.expect('should have value')); // 5
|
|
723
|
+
*
|
|
724
|
+
* const y = Err('error');
|
|
725
|
+
* y.expect('should have value'); // throws TypeError: should have value: error
|
|
726
|
+
* ```
|
|
286
727
|
*/
|
|
287
728
|
expect(msg: string): T;
|
|
288
729
|
/**
|
|
289
730
|
* Returns the contained `Ok` value.
|
|
290
731
|
* @throws {TypeError} Throws an error if the result is an `Err`.
|
|
732
|
+
* @see expect
|
|
733
|
+
* @see unwrapOr
|
|
734
|
+
* @see unwrapErr
|
|
735
|
+
* @example
|
|
736
|
+
* ```ts
|
|
737
|
+
* const x = Ok(5);
|
|
738
|
+
* console.log(x.unwrap()); // 5
|
|
739
|
+
*
|
|
740
|
+
* const y = Err('error');
|
|
741
|
+
* y.unwrap(); // throws TypeError
|
|
742
|
+
* ```
|
|
291
743
|
*/
|
|
292
744
|
unwrap(): T;
|
|
293
745
|
/**
|
|
294
746
|
* Returns the contained `Ok` value or a provided default.
|
|
295
747
|
* @param defaultValue - The value to return if the result is an `Err`.
|
|
748
|
+
* @see unwrapOrElse
|
|
749
|
+
* @example
|
|
750
|
+
* ```ts
|
|
751
|
+
* const x = Ok(5);
|
|
752
|
+
* console.log(x.unwrapOr(10)); // 5
|
|
753
|
+
*
|
|
754
|
+
* const y = Err('error');
|
|
755
|
+
* console.log(y.unwrapOr(10)); // 10
|
|
756
|
+
* ```
|
|
296
757
|
*/
|
|
297
758
|
unwrapOr(defaultValue: T): T;
|
|
298
759
|
/**
|
|
299
760
|
* Returns the contained `Ok` value or computes it from a closure if the result is `Err`.
|
|
300
761
|
* @param fn - A function that takes the `Err` value and returns an `Ok` value.
|
|
762
|
+
* @see unwrapOr
|
|
763
|
+
* @example
|
|
764
|
+
* ```ts
|
|
765
|
+
* const x = Err('error');
|
|
766
|
+
* console.log(x.unwrapOrElse(e => e.length)); // 5
|
|
767
|
+
* ```
|
|
301
768
|
*/
|
|
302
769
|
unwrapOrElse(fn: (error: E) => T): T;
|
|
770
|
+
/**
|
|
771
|
+
* Asynchronous version of `unwrapOrElse`.
|
|
772
|
+
* @param fn - An async function that takes the `Err` value and returns a `Promise<T>`.
|
|
773
|
+
* @returns A promise that resolves to the contained `Ok` value or the result of the async function.
|
|
774
|
+
* @see unwrapOrElse
|
|
775
|
+
* @example
|
|
776
|
+
* ```ts
|
|
777
|
+
* const x = Err('error');
|
|
778
|
+
* await x.unwrapOrElseAsync(async e => e.length); // 5
|
|
779
|
+
* ```
|
|
780
|
+
*/
|
|
781
|
+
unwrapOrElseAsync(fn: (error: E) => Promise<T>): Promise<T>;
|
|
303
782
|
/**
|
|
304
783
|
* These methods extract the contained value in a `Result<T, E>` when it is the `Err` variant.
|
|
305
784
|
*/
|
|
@@ -307,11 +786,31 @@ interface Result<T, E> {
|
|
|
307
786
|
* Returns the contained `Err` value, with a provided error message if the result is `Ok`.
|
|
308
787
|
* @param msg - The error message to provide if the result is an `Ok`.
|
|
309
788
|
* @throws {TypeError} Throws an error with the provided message if the result is an `Ok`.
|
|
789
|
+
* @see unwrapErr
|
|
790
|
+
* @see expect
|
|
791
|
+
* @example
|
|
792
|
+
* ```ts
|
|
793
|
+
* const x = Err('error');
|
|
794
|
+
* console.log(x.expectErr('should have error')); // 'error'
|
|
795
|
+
*
|
|
796
|
+
* const y = Ok(5);
|
|
797
|
+
* y.expectErr('should have error'); // throws TypeError: should have error: 5
|
|
798
|
+
* ```
|
|
310
799
|
*/
|
|
311
800
|
expectErr(msg: string): E;
|
|
312
801
|
/**
|
|
313
802
|
* Returns the contained `Err` value.
|
|
314
803
|
* @throws {TypeError} Throws an error if the result is an `Ok`.
|
|
804
|
+
* @see expectErr
|
|
805
|
+
* @see unwrap
|
|
806
|
+
* @example
|
|
807
|
+
* ```ts
|
|
808
|
+
* const x = Err('error');
|
|
809
|
+
* console.log(x.unwrapErr()); // 'error'
|
|
810
|
+
*
|
|
811
|
+
* const y = Ok(5);
|
|
812
|
+
* y.unwrapErr(); // throws TypeError
|
|
813
|
+
* ```
|
|
315
814
|
*/
|
|
316
815
|
unwrapErr(): E;
|
|
317
816
|
/**
|
|
@@ -321,22 +820,51 @@ interface Result<T, E> {
|
|
|
321
820
|
* Converts from `Result<T, E>` to `Option<T>`.
|
|
322
821
|
* If the result is `Ok`, returns `Some(T)`.
|
|
323
822
|
* If the result is `Err`, returns `None`.
|
|
823
|
+
* @see err
|
|
824
|
+
* @example
|
|
825
|
+
* ```ts
|
|
826
|
+
* const x = Ok(5);
|
|
827
|
+
* console.log(x.ok().unwrap()); // 5
|
|
828
|
+
*
|
|
829
|
+
* const y = Err('error');
|
|
830
|
+
* console.log(y.ok().isNone()); // true
|
|
831
|
+
* ```
|
|
324
832
|
*/
|
|
325
833
|
ok(): Option<T>;
|
|
326
834
|
/**
|
|
327
835
|
* Converts from `Result<T, E>` to `Option<E>`.
|
|
328
836
|
* If the result is `Err`, returns `Some(E)`.
|
|
329
837
|
* If the result is `Ok`, returns `None`.
|
|
838
|
+
* @see ok
|
|
839
|
+
* @example
|
|
840
|
+
* ```ts
|
|
841
|
+
* const x = Err('error');
|
|
842
|
+
* console.log(x.err().unwrap()); // 'error'
|
|
843
|
+
*
|
|
844
|
+
* const y = Ok(5);
|
|
845
|
+
* console.log(y.err().isNone()); // true
|
|
846
|
+
* ```
|
|
330
847
|
*/
|
|
331
848
|
err(): Option<E>;
|
|
332
849
|
/**
|
|
333
850
|
* Transposes a `Result` of an `Option` into an `Option` of a `Result`.
|
|
334
|
-
* @typeParam
|
|
851
|
+
* @typeParam U - The type of the success value in the `Ok` variant of the `Option`.
|
|
335
852
|
* @returns `Some` containing `Ok` if the result is `Ok` containing `Some`,
|
|
336
853
|
* `Some` containing `Err` if the result is `Err`,
|
|
337
854
|
* `None` if the result is `Ok` containing `None`.
|
|
855
|
+
* @example
|
|
856
|
+
* ```ts
|
|
857
|
+
* const x = Ok(Some(5));
|
|
858
|
+
* console.log(x.transpose().unwrap().unwrap()); // 5
|
|
859
|
+
*
|
|
860
|
+
* const y: Result<Option<number>, string> = Err('error');
|
|
861
|
+
* console.log(y.transpose().unwrap().unwrapErr()); // 'error'
|
|
862
|
+
*
|
|
863
|
+
* const z = Ok(None);
|
|
864
|
+
* console.log(z.transpose().isNone()); // true
|
|
865
|
+
* ```
|
|
338
866
|
*/
|
|
339
|
-
transpose<
|
|
867
|
+
transpose<U>(this: Result<Option<U>, E>): Option<Result<U, E>>;
|
|
340
868
|
/**
|
|
341
869
|
* This method transforms the contained value of the `Ok` variant:
|
|
342
870
|
*/
|
|
@@ -345,6 +873,16 @@ interface Result<T, E> {
|
|
|
345
873
|
* leaving an `Err` value untouched.
|
|
346
874
|
* @typeParam U - The type of the value returned by the map function.
|
|
347
875
|
* @param fn - A function that takes the `Ok` value and returns a new value.
|
|
876
|
+
* @see mapErr
|
|
877
|
+
* @see andThen
|
|
878
|
+
* @example
|
|
879
|
+
* ```ts
|
|
880
|
+
* const x = Ok(5);
|
|
881
|
+
* console.log(x.map(v => v * 2).unwrap()); // 10
|
|
882
|
+
*
|
|
883
|
+
* const y = Err('error');
|
|
884
|
+
* console.log(y.map(v => v * 2).unwrapErr()); // 'error'
|
|
885
|
+
* ```
|
|
348
886
|
*/
|
|
349
887
|
map<U>(fn: (value: T) => U): Result<U, E>;
|
|
350
888
|
/**
|
|
@@ -355,6 +893,12 @@ interface Result<T, E> {
|
|
|
355
893
|
* leaving an `Ok` value untouched.
|
|
356
894
|
* @typeParam F - The type of the error returned by the map function.
|
|
357
895
|
* @param fn - A function that takes the `Err` value and returns a new error value.
|
|
896
|
+
* @see map
|
|
897
|
+
* @example
|
|
898
|
+
* ```ts
|
|
899
|
+
* const x = Err('error');
|
|
900
|
+
* console.log(x.mapErr(e => e.toUpperCase()).unwrapErr()); // 'ERROR'
|
|
901
|
+
* ```
|
|
358
902
|
*/
|
|
359
903
|
mapErr<F>(fn: (error: E) => F): Result<T, F>;
|
|
360
904
|
/**
|
|
@@ -365,6 +909,15 @@ interface Result<T, E> {
|
|
|
365
909
|
* @typeParam U - The type of the value returned by the map function or the default value.
|
|
366
910
|
* @param defaultValue - The value to return if the result is `Err`.
|
|
367
911
|
* @param fn - A function that takes the `Ok` value and returns a new value.
|
|
912
|
+
* @see mapOrElse
|
|
913
|
+
* @example
|
|
914
|
+
* ```ts
|
|
915
|
+
* const x = Ok(5);
|
|
916
|
+
* console.log(x.mapOr(0, v => v * 2)); // 10
|
|
917
|
+
*
|
|
918
|
+
* const y = Err('error');
|
|
919
|
+
* console.log(y.mapOr(0, v => v * 2)); // 0
|
|
920
|
+
* ```
|
|
368
921
|
*/
|
|
369
922
|
mapOr<U>(defaultValue: U, fn: (value: T) => U): U;
|
|
370
923
|
/**
|
|
@@ -372,14 +925,32 @@ interface Result<T, E> {
|
|
|
372
925
|
* @typeParam U - The type of the value returned by the map function or the default function.
|
|
373
926
|
* @param defaultFn - A function that returns the default value.
|
|
374
927
|
* @param fn - A function that takes the `Ok` value and returns a new value.
|
|
928
|
+
* @see mapOr
|
|
929
|
+
* @example
|
|
930
|
+
* ```ts
|
|
931
|
+
* const x = Ok(5);
|
|
932
|
+
* console.log(x.mapOrElse(e => 0, v => v * 2)); // 10
|
|
933
|
+
*
|
|
934
|
+
* const y = Err('error');
|
|
935
|
+
* console.log(y.mapOrElse(e => e.length, v => v * 2)); // 5
|
|
936
|
+
* ```
|
|
375
937
|
*/
|
|
376
938
|
mapOrElse<U>(defaultFn: (error: E) => U, fn: (value: T) => U): U;
|
|
377
939
|
/**
|
|
378
|
-
* Converts from `Result<Result<
|
|
379
|
-
* If the result is `Ok(Ok(
|
|
940
|
+
* Converts from `Result<Result<U, E>, E>` to `Result<U, E>`.
|
|
941
|
+
* If the result is `Ok(Ok(U))`, returns `Ok(U)`.
|
|
380
942
|
* If the result is `Ok(Err(E))` or `Err(E)`, returns `Err(E)`.
|
|
943
|
+
* @typeParam U - The type of the success value in the inner `Result`.
|
|
944
|
+
* @example
|
|
945
|
+
* ```ts
|
|
946
|
+
* const x = Ok(Ok(5));
|
|
947
|
+
* console.log(x.flatten().unwrap()); // 5
|
|
948
|
+
*
|
|
949
|
+
* const y = Ok(Err('error'));
|
|
950
|
+
* console.log(y.flatten().unwrapErr()); // 'error'
|
|
951
|
+
* ```
|
|
381
952
|
*/
|
|
382
|
-
flatten<
|
|
953
|
+
flatten<U>(this: Result<Result<U, E>, E>): Result<U, E>;
|
|
383
954
|
/**
|
|
384
955
|
* These methods treat the `Result` as a boolean value, where `Ok` acts like `true` and `Err` acts like `false`.
|
|
385
956
|
*/
|
|
@@ -388,6 +959,17 @@ interface Result<T, E> {
|
|
|
388
959
|
* @typeParam U - The type of the value in the other `Result`.
|
|
389
960
|
* @param other - The `Result` to return if `this` is `Ok`.
|
|
390
961
|
* @returns The passed `Result` if `this` is `Ok`, otherwise returns `this` (which is `Err`).
|
|
962
|
+
* @see or
|
|
963
|
+
* @example
|
|
964
|
+
* ```ts
|
|
965
|
+
* const x = Ok(2);
|
|
966
|
+
* const y = Err('late error');
|
|
967
|
+
* console.log(x.and(y).unwrapErr()); // 'late error'
|
|
968
|
+
*
|
|
969
|
+
* const a = Err('early error');
|
|
970
|
+
* const b = Ok(5);
|
|
971
|
+
* console.log(a.and(b).unwrapErr()); // 'early error'
|
|
972
|
+
* ```
|
|
391
973
|
*/
|
|
392
974
|
and<U>(other: Result<U, E>): Result<U, E>;
|
|
393
975
|
/**
|
|
@@ -395,6 +977,17 @@ interface Result<T, E> {
|
|
|
395
977
|
* @typeParam F - The type of the error in the other `Result`.
|
|
396
978
|
* @param other - The `Result` to return if `this` is `Err`.
|
|
397
979
|
* @returns `this` if it is `Ok`, otherwise returns `other`.
|
|
980
|
+
* @see and
|
|
981
|
+
* @example
|
|
982
|
+
* ```ts
|
|
983
|
+
* const x = Err('error');
|
|
984
|
+
* const y = Ok(5);
|
|
985
|
+
* console.log(x.or(y).unwrap()); // 5
|
|
986
|
+
*
|
|
987
|
+
* const a = Ok(2);
|
|
988
|
+
* const b = Ok(100);
|
|
989
|
+
* console.log(a.or(b).unwrap()); // 2
|
|
990
|
+
* ```
|
|
398
991
|
*/
|
|
399
992
|
or<F>(other: Result<T, F>): Result<T, F>;
|
|
400
993
|
/**
|
|
@@ -402,20 +995,77 @@ interface Result<T, E> {
|
|
|
402
995
|
* @typeParam U - The type of the value returned by the function.
|
|
403
996
|
* @param fn - A function that takes the `Ok` value and returns a `Result`.
|
|
404
997
|
* @returns The result of `fn` if `this` is `Ok`, otherwise `this` as `Err`.
|
|
998
|
+
* @see map
|
|
999
|
+
* @see orElse
|
|
1000
|
+
* @example
|
|
1001
|
+
* ```ts
|
|
1002
|
+
* const x = Ok(2);
|
|
1003
|
+
* const result = x.andThen(v => v > 0 ? Ok(v * 2) : Err('negative'));
|
|
1004
|
+
* console.log(result.unwrap()); // 4
|
|
1005
|
+
*
|
|
1006
|
+
* const y = Err('error');
|
|
1007
|
+
* console.log(y.andThen(v => Ok(v * 2)).unwrapErr()); // 'error'
|
|
1008
|
+
* ```
|
|
405
1009
|
*/
|
|
406
1010
|
andThen<U>(fn: (value: T) => Result<U, E>): Result<U, E>;
|
|
1011
|
+
/**
|
|
1012
|
+
* Asynchronous version of `andThen`.
|
|
1013
|
+
* @typeParam U - The type of the value returned by the async function.
|
|
1014
|
+
* @param fn - An async function that takes the `Ok` value and returns a `Promise<Result<U, E>>`.
|
|
1015
|
+
* @returns A promise that resolves to `this` as `Err` if `this` is `Err`, otherwise the result of `fn`.
|
|
1016
|
+
* @see andThen
|
|
1017
|
+
* @see orElseAsync
|
|
1018
|
+
* @example
|
|
1019
|
+
* ```ts
|
|
1020
|
+
* const x = Ok(2);
|
|
1021
|
+
* const result = await x.andThenAsync(async v => Ok(v * 2));
|
|
1022
|
+
* console.log(result.unwrap()); // 4
|
|
1023
|
+
* ```
|
|
1024
|
+
*/
|
|
1025
|
+
andThenAsync<U>(fn: (value: T) => AsyncResult<U, E>): AsyncResult<U, E>;
|
|
407
1026
|
/**
|
|
408
1027
|
* Calls the provided function with the contained error if `this` is `Err`, otherwise returns `this` as `Ok`.
|
|
409
1028
|
* @typeParam F - The type of the error returned by the function.
|
|
410
1029
|
* @param fn - A function that takes the `Err` value and returns a `Result`.
|
|
411
1030
|
* @returns The result of `fn` if `this` is `Err`, otherwise `this` as `Ok`.
|
|
1031
|
+
* @see andThen
|
|
1032
|
+
* @example
|
|
1033
|
+
* ```ts
|
|
1034
|
+
* const x = Err('error');
|
|
1035
|
+
* const result = x.orElse(e => Ok(e.length));
|
|
1036
|
+
* console.log(result.unwrap()); // 5
|
|
1037
|
+
*
|
|
1038
|
+
* const y = Ok(2);
|
|
1039
|
+
* console.log(y.orElse(e => Ok(0)).unwrap()); // 2
|
|
1040
|
+
* ```
|
|
412
1041
|
*/
|
|
413
1042
|
orElse<F>(fn: (error: E) => Result<T, F>): Result<T, F>;
|
|
1043
|
+
/**
|
|
1044
|
+
* Asynchronous version of `orElse`.
|
|
1045
|
+
* @typeParam F - The type of the error returned by the async function.
|
|
1046
|
+
* @param fn - An async function that takes the `Err` value and returns a `Promise<Result<T, F>>`.
|
|
1047
|
+
* @returns A promise that resolves to `this` as `Ok` if `this` is `Ok`, otherwise the result of `fn`.
|
|
1048
|
+
* @see orElse
|
|
1049
|
+
* @see andThenAsync
|
|
1050
|
+
* @example
|
|
1051
|
+
* ```ts
|
|
1052
|
+
* const x = Err('error');
|
|
1053
|
+
* const result = await x.orElseAsync(async e => Ok(e.length));
|
|
1054
|
+
* console.log(result.unwrap()); // 5
|
|
1055
|
+
* ```
|
|
1056
|
+
*/
|
|
1057
|
+
orElseAsync<F>(fn: (error: E) => AsyncResult<T, F>): AsyncResult<T, F>;
|
|
414
1058
|
/**
|
|
415
1059
|
* Calls the provided function with the contained value if `this` is `Ok`, for side effects only.
|
|
416
1060
|
* Does not modify the `Result`.
|
|
417
1061
|
* @param fn - A function to call with the `Ok` value.
|
|
418
1062
|
* @returns `this`, unmodified.
|
|
1063
|
+
* @see inspectErr
|
|
1064
|
+
* @example
|
|
1065
|
+
* ```ts
|
|
1066
|
+
* const x = Ok(5);
|
|
1067
|
+
* x.inspect(v => console.log(v)); // prints 5
|
|
1068
|
+
* ```
|
|
419
1069
|
*/
|
|
420
1070
|
inspect(fn: (value: T) => void): this;
|
|
421
1071
|
/**
|
|
@@ -423,81 +1073,155 @@ interface Result<T, E> {
|
|
|
423
1073
|
* Does not modify the `Result`.
|
|
424
1074
|
* @param fn - A function to call with the `Err` value.
|
|
425
1075
|
* @returns `this`, unmodified.
|
|
1076
|
+
* @see inspect
|
|
1077
|
+
* @example
|
|
1078
|
+
* ```ts
|
|
1079
|
+
* const x = Err('error');
|
|
1080
|
+
* x.inspectErr(e => console.log(e)); // prints 'error'
|
|
1081
|
+
* ```
|
|
426
1082
|
*/
|
|
427
1083
|
inspectErr(fn: (error: E) => void): this;
|
|
428
1084
|
/**
|
|
429
1085
|
* Tests whether `this` and `other` are both `Ok` containing equal values, or both are `Err` containing equal errors.
|
|
430
1086
|
* @param other - The other `Result` to compare with.
|
|
431
1087
|
* @returns `true` if `this` and `other` are both `Ok` with equal values, or both are `Err` with equal errors, otherwise `false`.
|
|
1088
|
+
* @example
|
|
1089
|
+
* ```ts
|
|
1090
|
+
* const a = Ok(5);
|
|
1091
|
+
* const b = Ok(5);
|
|
1092
|
+
* const c = Ok(10);
|
|
1093
|
+
* console.log(a.eq(b)); // true
|
|
1094
|
+
* console.log(a.eq(c)); // false
|
|
1095
|
+
*
|
|
1096
|
+
* const d = Err('error');
|
|
1097
|
+
* const e = Err('error');
|
|
1098
|
+
* console.log(d.eq(e)); // true
|
|
1099
|
+
* console.log(a.eq(d)); // false
|
|
1100
|
+
* ```
|
|
432
1101
|
*/
|
|
433
1102
|
eq(other: Result<T, E>): boolean;
|
|
434
1103
|
/**
|
|
435
|
-
* Transforms the current Result into a new Result where the type of the error
|
|
436
|
-
* The type of the success
|
|
437
|
-
*
|
|
1104
|
+
* Transforms the current Result into a new Result where the type of the error is replaced with a new type `F`.
|
|
1105
|
+
* The type of the success value remains unchanged.
|
|
1106
|
+
* This is a type-level only operation, equivalent to `result as unknown as Result<T, F>`.
|
|
438
1107
|
*
|
|
439
|
-
* @typeParam F - The new type for the error
|
|
440
|
-
* @returns `this`
|
|
1108
|
+
* @typeParam F - The new type for the error.
|
|
1109
|
+
* @returns `this` with the error type cast to `F`.
|
|
1110
|
+
* @see asErr
|
|
1111
|
+
* @example
|
|
1112
|
+
* ```ts
|
|
1113
|
+
* const x: Result<number, string> = Ok(5);
|
|
1114
|
+
* const y: Result<number, Error> = x.asOk<Error>();
|
|
1115
|
+
* console.log(y.unwrap()); // 5
|
|
1116
|
+
* ```
|
|
441
1117
|
*/
|
|
442
1118
|
asOk<F>(): Result<T, F>;
|
|
443
1119
|
/**
|
|
444
|
-
* Transforms the current Result into a new Result where the type of the success
|
|
445
|
-
* The type of the error
|
|
446
|
-
*
|
|
447
|
-
*
|
|
1120
|
+
* Transforms the current Result into a new Result where the type of the success value is replaced with a new type `U`.
|
|
1121
|
+
* The type of the error remains unchanged.
|
|
1122
|
+
* This is a type-level only operation, equivalent to `result as unknown as Result<U, E>`.
|
|
1123
|
+
* Useful when you need to propagate an error to a different success type context.
|
|
448
1124
|
*
|
|
449
|
-
* @typeParam U - The new type for the success
|
|
450
|
-
* @returns `this`
|
|
1125
|
+
* @typeParam U - The new type for the success value.
|
|
1126
|
+
* @returns `this` with the success type cast to `U`.
|
|
1127
|
+
* @see asOk
|
|
1128
|
+
* @example
|
|
1129
|
+
* ```ts
|
|
1130
|
+
* const x: Result<number, string> = Err('error');
|
|
1131
|
+
* const y: Result<string, string> = x.asErr<string>();
|
|
1132
|
+
* console.log(y.unwrapErr()); // 'error'
|
|
1133
|
+
* ```
|
|
451
1134
|
*/
|
|
452
1135
|
asErr<U>(): Result<U, E>;
|
|
453
1136
|
/**
|
|
454
1137
|
* Custom `toString` implementation that uses the `Result`'s contained value.
|
|
1138
|
+
* @example
|
|
1139
|
+
* ```ts
|
|
1140
|
+
* console.log(Ok(5).toString()); // 'Ok(5)'
|
|
1141
|
+
* console.log(Err('error').toString()); // 'Err(error)'
|
|
1142
|
+
* ```
|
|
455
1143
|
*/
|
|
456
1144
|
toString(): string;
|
|
457
1145
|
}
|
|
1146
|
+
/**
|
|
1147
|
+
* Represents an asynchronous operation that yields an `Option<T>`.
|
|
1148
|
+
* This is a promise that resolves to either `Some(T)` if the value is present, or `None` if the value is absent.
|
|
1149
|
+
*
|
|
1150
|
+
* @typeParam T - The type of the value that may be contained within the `Option`.
|
|
1151
|
+
*/
|
|
1152
|
+
type AsyncOption<T> = Promise<Option<T>>;
|
|
1153
|
+
/**
|
|
1154
|
+
* Represents an asynchronous operation that yields a `Result<T, E>`.
|
|
1155
|
+
* This is a promise that resolves to `Ok(T)` if the operation was successful, or `Err(E)` if there was an error.
|
|
1156
|
+
*
|
|
1157
|
+
* @typeParam T - The type of the value that is produced by a successful operation.
|
|
1158
|
+
* @typeParam E - The type of the error that may be produced by a failed operation.
|
|
1159
|
+
*/
|
|
1160
|
+
type AsyncResult<T, E> = Promise<Result<T, E>>;
|
|
458
1161
|
|
|
459
1162
|
/**
|
|
460
|
-
*
|
|
1163
|
+
* @fileoverview
|
|
1164
|
+
* Pre-defined Result constants for common return values.
|
|
1165
|
+
*
|
|
1166
|
+
* These immutable constants can be reused throughout the application to avoid
|
|
1167
|
+
* creating new Result instances for common values like `true`, `false`, `0`, and `void`.
|
|
461
1168
|
*/
|
|
1169
|
+
|
|
462
1170
|
/**
|
|
463
1171
|
* Result constant for `true`.
|
|
464
1172
|
* Can be used anywhere due to immutability.
|
|
1173
|
+
* @example
|
|
1174
|
+
* ```ts
|
|
1175
|
+
* function validate(): Result<boolean, Error> {
|
|
1176
|
+
* return RESULT_TRUE;
|
|
1177
|
+
* }
|
|
1178
|
+
* ```
|
|
465
1179
|
*/
|
|
466
1180
|
declare const RESULT_TRUE: Result<boolean, any>;
|
|
467
1181
|
/**
|
|
468
1182
|
* Result constant for `false`.
|
|
469
1183
|
* Can be used anywhere due to immutability.
|
|
1184
|
+
* @example
|
|
1185
|
+
* ```ts
|
|
1186
|
+
* function validate(): Result<boolean, Error> {
|
|
1187
|
+
* return RESULT_FALSE;
|
|
1188
|
+
* }
|
|
1189
|
+
* ```
|
|
470
1190
|
*/
|
|
471
1191
|
declare const RESULT_FALSE: Result<boolean, any>;
|
|
472
1192
|
/**
|
|
473
1193
|
* Result constant for `0`.
|
|
474
1194
|
* Can be used anywhere due to immutability.
|
|
1195
|
+
* @example
|
|
1196
|
+
* ```ts
|
|
1197
|
+
* function count(): Result<number, Error> {
|
|
1198
|
+
* return RESULT_ZERO;
|
|
1199
|
+
* }
|
|
1200
|
+
* ```
|
|
475
1201
|
*/
|
|
476
1202
|
declare const RESULT_ZERO: Result<number, any>;
|
|
477
1203
|
/**
|
|
478
1204
|
* Result constant for `void` or `()`.
|
|
1205
|
+
* Can be used anywhere due to immutability.
|
|
1206
|
+
* @example
|
|
1207
|
+
* ```ts
|
|
1208
|
+
* function doSomething(): Result<void, Error> {
|
|
1209
|
+
* return RESULT_VOID;
|
|
1210
|
+
* }
|
|
1211
|
+
* ```
|
|
479
1212
|
*/
|
|
480
1213
|
declare const RESULT_VOID: Result<void, any>;
|
|
481
1214
|
|
|
482
1215
|
/**
|
|
483
|
-
*
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
/**
|
|
487
|
-
* Represents an asynchronous operation that yields an `Option<T>`.
|
|
488
|
-
* This is a promise that resolves to either `Some(T)` if the value is present, or `None` if the value is absent.
|
|
489
|
-
*
|
|
490
|
-
* @typeParam T - The type of the value that may be contained within the `Option`.
|
|
491
|
-
*/
|
|
492
|
-
type AsyncOption<T> = Promise<Option<T>>;
|
|
493
|
-
/**
|
|
494
|
-
* Represents an asynchronous operation that yields a `Result<T, E>`.
|
|
495
|
-
* This is a promise that resolves to `Ok(T)` if the operation was successful, or `Err(E)` if there was an error.
|
|
1216
|
+
* @fileoverview
|
|
1217
|
+
* Type aliases for commonly used `Result` type combinations.
|
|
496
1218
|
*
|
|
497
|
-
*
|
|
498
|
-
*
|
|
1219
|
+
* These types provide convenient shortcuts for common patterns like:
|
|
1220
|
+
* - Operations that return nothing on success (`VoidResult`)
|
|
1221
|
+
* - I/O operations that may fail with an Error (`IOResult`)
|
|
1222
|
+
* - Async versions of the above
|
|
499
1223
|
*/
|
|
500
|
-
|
|
1224
|
+
|
|
501
1225
|
/**
|
|
502
1226
|
* Similar to Rust's `Result<(), E>`.
|
|
503
1227
|
*
|
|
@@ -533,10 +1257,20 @@ type VoidIOResult = IOResult<void>;
|
|
|
533
1257
|
*/
|
|
534
1258
|
type AsyncVoidIOResult = AsyncIOResult<void>;
|
|
535
1259
|
|
|
1260
|
+
/**
|
|
1261
|
+
* @fileoverview
|
|
1262
|
+
* Extension functions for bridging Promise-based APIs with the Result type.
|
|
1263
|
+
*
|
|
1264
|
+
* This module provides utilities for integrating async/await patterns with Result-based error handling.
|
|
1265
|
+
*/
|
|
1266
|
+
|
|
536
1267
|
/**
|
|
537
1268
|
* Converts a Promise to a Result type, capturing the resolved value in an `Ok`, or the error in an `Err`.
|
|
538
1269
|
* This allows for promise-based asynchronous operations to be handled in a way that is more in line with the Result pattern.
|
|
539
1270
|
*
|
|
1271
|
+
* Note: JavaScript promises can reject with any value, not just `Error` objects.
|
|
1272
|
+
* The error is cast to type `E`, so ensure your error handling accounts for this.
|
|
1273
|
+
*
|
|
540
1274
|
* @typeParam T - The type of the value that the promise resolves to.
|
|
541
1275
|
* @typeParam E - The type of the error that the promise may reject with, defaults to `Error`.
|
|
542
1276
|
* @param p - The promise to convert into a `Result` type.
|
|
@@ -553,9 +1287,27 @@ type AsyncVoidIOResult = AsyncIOResult<void>;
|
|
|
553
1287
|
* });
|
|
554
1288
|
* }
|
|
555
1289
|
* ```
|
|
1290
|
+
*
|
|
1291
|
+
* @example
|
|
1292
|
+
* ```ts
|
|
1293
|
+
* // With custom error type
|
|
1294
|
+
* const result = await promiseToAsyncResult<User, ApiError>(fetchUser(id));
|
|
1295
|
+
* ```
|
|
556
1296
|
*/
|
|
557
1297
|
declare function promiseToAsyncResult<T, E = Error>(p: Promise<T>): Promise<Result<T, E>>;
|
|
558
1298
|
|
|
1299
|
+
/**
|
|
1300
|
+
* @fileoverview
|
|
1301
|
+
* Constructors and factory functions for creating `Option` and `Result` types.
|
|
1302
|
+
*
|
|
1303
|
+
* This module exports:
|
|
1304
|
+
* - `Some<T>(value)` - Creates an Option containing a value
|
|
1305
|
+
* - `None` - Constant representing absence of value
|
|
1306
|
+
* - `Ok<T, E>(value)` - Creates a successful Result
|
|
1307
|
+
* - `Err<T, E>(error)` - Creates a failed Result
|
|
1308
|
+
* - `None` interface - Type overrides for better type inference
|
|
1309
|
+
*/
|
|
1310
|
+
|
|
559
1311
|
/**
|
|
560
1312
|
* Creates an `Option<T>` representing the presence of a value.
|
|
561
1313
|
* This function is typically used to construct an `Option` that contains a value, indicating that the operation yielding the value was successful.
|
|
@@ -582,25 +1334,59 @@ interface None extends Option<never> {
|
|
|
582
1334
|
* When using `None` alone, the following overrides can make type inference more accurate.
|
|
583
1335
|
*/
|
|
584
1336
|
readonly [OptionKindSymbol]: 'None';
|
|
1337
|
+
isSome(): false;
|
|
1338
|
+
isNone(): true;
|
|
1339
|
+
isSomeAnd(predicate: (value: never) => boolean): false;
|
|
1340
|
+
isSomeAndAsync(predicate: (value: never) => Promise<boolean>): Promise<false>;
|
|
1341
|
+
isNoneOr(predicate: (value: never) => boolean): true;
|
|
1342
|
+
isNoneOrAsync(predicate: (value: never) => Promise<boolean>): Promise<true>;
|
|
1343
|
+
expect(msg: string): never;
|
|
1344
|
+
unwrap(): never;
|
|
585
1345
|
unwrapOr<T>(defaultValue: T): T;
|
|
586
1346
|
unwrapOrElse<T>(fn: () => T): T;
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
1347
|
+
unwrapOrElseAsync<T>(fn: () => Promise<T>): Promise<T>;
|
|
1348
|
+
okOr<E>(error: E): Result<never, E>;
|
|
1349
|
+
okOrElse<E>(err: () => E): Result<never, E>;
|
|
1350
|
+
transpose(): Result<this, never>;
|
|
1351
|
+
filter(predicate: (value: never) => boolean): this;
|
|
1352
|
+
flatten(): this;
|
|
1353
|
+
map<U>(fn: (value: never) => U): this;
|
|
1354
|
+
mapOr<U>(defaultValue: U, fn: (value: never) => U): U;
|
|
1355
|
+
mapOrElse<U>(defaultFn: () => U, fn: (value: never) => U): U;
|
|
1356
|
+
zip<U>(other: Option<U>): this;
|
|
1357
|
+
zipWith<U, R>(other: Option<U>, fn: (value: never, otherValue: U) => R): this;
|
|
1358
|
+
unzip(): [this, this];
|
|
1359
|
+
and<U>(other: Option<U>): this;
|
|
1360
|
+
andThen<U>(fn: (value: never) => Option<U>): this;
|
|
1361
|
+
andThenAsync<U>(fn: (value: never) => AsyncOption<U>): Promise<this>;
|
|
596
1362
|
or<T>(other: Option<T>): Option<T>;
|
|
597
1363
|
orElse<T>(fn: () => Option<T>): Option<T>;
|
|
1364
|
+
orElseAsync<T>(fn: () => AsyncOption<T>): AsyncOption<T>;
|
|
598
1365
|
xor<T>(other: Option<T>): Option<T>;
|
|
1366
|
+
inspect(fn: (value: never) => void): this;
|
|
599
1367
|
eq<T>(other: Option<T>): boolean;
|
|
600
1368
|
}
|
|
601
1369
|
/**
|
|
602
1370
|
* A constant representing the `None` case of an `Option`, indicating the absence of a value.
|
|
603
1371
|
* This constant is frozen to ensure it is immutable and cannot be altered, preserving the integrity of `None` throughout the application.
|
|
1372
|
+
*
|
|
1373
|
+
* @example
|
|
1374
|
+
* ```ts
|
|
1375
|
+
* // Use None to represent absence of a value
|
|
1376
|
+
* function findUser(id: number): Option<User> {
|
|
1377
|
+
* const user = users.find(u => u.id === id);
|
|
1378
|
+
* return user ? Some(user) : None;
|
|
1379
|
+
* }
|
|
1380
|
+
*
|
|
1381
|
+
* // None is a singleton, so you can compare by reference
|
|
1382
|
+
* const result = findUser(999);
|
|
1383
|
+
* if (result === None) {
|
|
1384
|
+
* console.log('User not found');
|
|
1385
|
+
* }
|
|
1386
|
+
*
|
|
1387
|
+
* // Use with Option methods
|
|
1388
|
+
* const name = None.unwrapOr('Anonymous'); // 'Anonymous'
|
|
1389
|
+
* ```
|
|
604
1390
|
*/
|
|
605
1391
|
declare const None: None;
|
|
606
1392
|
/**
|
|
@@ -620,11 +1406,35 @@ declare const None: None;
|
|
|
620
1406
|
* }
|
|
621
1407
|
* ```
|
|
622
1408
|
*/
|
|
623
|
-
declare function Ok<T, E>(value: T): Result<T, E>;
|
|
1409
|
+
declare function Ok<T, E = never>(value: T): Result<T, E>;
|
|
624
1410
|
/**
|
|
625
|
-
*
|
|
1411
|
+
* Creates a `Result<void, E>` representing a successful outcome with no value.
|
|
1412
|
+
* This overload is used when the operation succeeds but doesn't produce a meaningful value.
|
|
1413
|
+
*
|
|
1414
|
+
* In Rust, this would be `Ok(())` using the unit type `()`.
|
|
1415
|
+
* Since JavaScript doesn't have a unit type, we use `void` instead.
|
|
1416
|
+
*
|
|
1417
|
+
* @typeParam E - The type of the error that the result could potentially contain.
|
|
1418
|
+
* @returns A `Result<void, E>` representing a successful operation with no value.
|
|
1419
|
+
*
|
|
1420
|
+
* @example
|
|
1421
|
+
* ```ts
|
|
1422
|
+
* function saveToFile(path: string): Result<void, Error> {
|
|
1423
|
+
* try {
|
|
1424
|
+
* fs.writeFileSync(path, data);
|
|
1425
|
+
* return Ok(); // Success with no return value
|
|
1426
|
+
* } catch (e) {
|
|
1427
|
+
* return Err(e as Error);
|
|
1428
|
+
* }
|
|
1429
|
+
* }
|
|
1430
|
+
*
|
|
1431
|
+
* const result = saveToFile('/tmp/data.txt');
|
|
1432
|
+
* if (result.isOk()) {
|
|
1433
|
+
* console.log('File saved successfully');
|
|
1434
|
+
* }
|
|
1435
|
+
* ```
|
|
626
1436
|
*/
|
|
627
|
-
declare function Ok<E>(): Result<void, E>;
|
|
1437
|
+
declare function Ok<E = never>(): Result<void, E>;
|
|
628
1438
|
/**
|
|
629
1439
|
* Creates a `Result<T, E>` representing a failed outcome containing an error.
|
|
630
1440
|
* This function is used to construct a `Result` that signifies the operation failed by containing the error `E`.
|
|
@@ -642,7 +1452,14 @@ declare function Ok<E>(): Result<void, E>;
|
|
|
642
1452
|
* }
|
|
643
1453
|
* ```
|
|
644
1454
|
*/
|
|
645
|
-
declare function Err<T, E>(error: E): Result<T, E>;
|
|
1455
|
+
declare function Err<T = never, E = unknown>(error: E): Result<T, E>;
|
|
1456
|
+
|
|
1457
|
+
/**
|
|
1458
|
+
* @fileoverview
|
|
1459
|
+
* Type guard utilities for checking if values are `Option` or `Result` types.
|
|
1460
|
+
*
|
|
1461
|
+
* These functions provide runtime type checking capabilities for the Option and Result types.
|
|
1462
|
+
*/
|
|
646
1463
|
|
|
647
1464
|
/**
|
|
648
1465
|
* Checks if a value is an `Option`.
|
|
@@ -650,6 +1467,13 @@ declare function Err<T, E>(error: E): Result<T, E>;
|
|
|
650
1467
|
* @typeParam T - The expected type of the value contained within the `Option`.
|
|
651
1468
|
* @param o - The value to be checked as an `Option`.
|
|
652
1469
|
* @returns `true` if the value is an `Option`, otherwise `false`.
|
|
1470
|
+
* @example
|
|
1471
|
+
* ```ts
|
|
1472
|
+
* const x = Some(5);
|
|
1473
|
+
* console.log(isOption(x)); // true
|
|
1474
|
+
* console.log(isOption(null)); // false
|
|
1475
|
+
* console.log(isOption({ value: 5 })); // false
|
|
1476
|
+
* ```
|
|
653
1477
|
*/
|
|
654
1478
|
declare function isOption<T>(o: unknown): o is Option<T>;
|
|
655
1479
|
/**
|
|
@@ -659,8 +1483,1188 @@ declare function isOption<T>(o: unknown): o is Option<T>;
|
|
|
659
1483
|
* @typeParam E - The expected type of the error value contained within the `Result`.
|
|
660
1484
|
* @param r - The value to be checked as a `Result`.
|
|
661
1485
|
* @returns `true` if the value is a `Result`, otherwise `false`.
|
|
1486
|
+
* @example
|
|
1487
|
+
* ```ts
|
|
1488
|
+
* const x = Ok(5);
|
|
1489
|
+
* console.log(isResult(x)); // true
|
|
1490
|
+
* console.log(isResult(null)); // false
|
|
1491
|
+
* console.log(isResult({ value: 5 })); // false
|
|
1492
|
+
* ```
|
|
662
1493
|
*/
|
|
663
1494
|
declare function isResult<T, E>(r: unknown): r is Result<T, E>;
|
|
664
1495
|
|
|
665
|
-
|
|
666
|
-
|
|
1496
|
+
/**
|
|
1497
|
+
* @fileoverview
|
|
1498
|
+
* Internal symbols used to identify `ControlFlow` type variants.
|
|
1499
|
+
*
|
|
1500
|
+
* These symbols are used as property keys to distinguish between `Break` and `Continue` variants.
|
|
1501
|
+
* They provide a reliable way to identify the variant of a `ControlFlow` instance without
|
|
1502
|
+
* relying on method calls or duck typing.
|
|
1503
|
+
*
|
|
1504
|
+
* Note: These symbols are internal implementation details and are not exported as part of the public API.
|
|
1505
|
+
* Use the `isControlFlow` utility function for type checking instead.
|
|
1506
|
+
*/
|
|
1507
|
+
/**
|
|
1508
|
+
* A unique symbol used as a property key to identify the variant of a `ControlFlow` instance.
|
|
1509
|
+
*
|
|
1510
|
+
* When accessed on a `ControlFlow`, returns `'Break'` if the ControlFlow signals early exit,
|
|
1511
|
+
* or `'Continue'` if it signals to proceed as normal.
|
|
1512
|
+
*
|
|
1513
|
+
* This symbol is used internally by the `isControlFlow` utility function to verify
|
|
1514
|
+
* that an object is a valid `ControlFlow` instance.
|
|
1515
|
+
*
|
|
1516
|
+
* @internal
|
|
1517
|
+
*/
|
|
1518
|
+
declare const ControlFlowKindSymbol: unique symbol;
|
|
1519
|
+
|
|
1520
|
+
/**
|
|
1521
|
+
* @fileoverview
|
|
1522
|
+
* Rust-inspired [ControlFlow](https://doc.rust-lang.org/std/ops/enum.ControlFlow.html) for control flow handling.
|
|
1523
|
+
*
|
|
1524
|
+
* `ControlFlow` is used to tell an operation whether it should exit early or go on as usual.
|
|
1525
|
+
* This is useful for:
|
|
1526
|
+
* - Short-circuiting iterators
|
|
1527
|
+
* - Signaling early termination in fold-like operations
|
|
1528
|
+
* - Implementing custom control flow patterns
|
|
1529
|
+
*/
|
|
1530
|
+
|
|
1531
|
+
/**
|
|
1532
|
+
* Used to tell an operation whether it should exit early or go on as usual.
|
|
1533
|
+
*
|
|
1534
|
+
* This is the return type of `try_fold` and similar iterator methods that support
|
|
1535
|
+
* short-circuiting. It can also be used in custom control flow scenarios.
|
|
1536
|
+
*
|
|
1537
|
+
* @typeParam B - The type of the value returned on `Break` (early exit).
|
|
1538
|
+
* @typeParam C - The type of the value returned on `Continue` (default: `void`).
|
|
1539
|
+
*
|
|
1540
|
+
* @example
|
|
1541
|
+
* ```ts
|
|
1542
|
+
* // Using ControlFlow to short-circuit a search
|
|
1543
|
+
* function findFirstNegative(numbers: number[]): Option<number> {
|
|
1544
|
+
* let result: Option<number> = None;
|
|
1545
|
+
*
|
|
1546
|
+
* for (const n of numbers) {
|
|
1547
|
+
* const flow = n < 0 ? Break(n) : Continue();
|
|
1548
|
+
* if (flow.isBreak()) {
|
|
1549
|
+
* result = Some(flow.breakValue().unwrap());
|
|
1550
|
+
* break;
|
|
1551
|
+
* }
|
|
1552
|
+
* }
|
|
1553
|
+
*
|
|
1554
|
+
* return result;
|
|
1555
|
+
* }
|
|
1556
|
+
* ```
|
|
1557
|
+
*
|
|
1558
|
+
* @example
|
|
1559
|
+
* ```ts
|
|
1560
|
+
* // Using ControlFlow in a custom fold operation
|
|
1561
|
+
* function tryFold<T, Acc>(
|
|
1562
|
+
* arr: T[],
|
|
1563
|
+
* init: Acc,
|
|
1564
|
+
* f: (acc: Acc, item: T) => ControlFlow<Acc, Acc>
|
|
1565
|
+
* ): ControlFlow<Acc, Acc> {
|
|
1566
|
+
* let acc = init;
|
|
1567
|
+
* for (const item of arr) {
|
|
1568
|
+
* const flow = f(acc, item);
|
|
1569
|
+
* if (flow.isBreak()) {
|
|
1570
|
+
* return flow;
|
|
1571
|
+
* }
|
|
1572
|
+
* acc = flow.continueValue().unwrap();
|
|
1573
|
+
* }
|
|
1574
|
+
* return Continue(acc);
|
|
1575
|
+
* }
|
|
1576
|
+
* ```
|
|
1577
|
+
*/
|
|
1578
|
+
interface ControlFlow<B, C = void> {
|
|
1579
|
+
/**
|
|
1580
|
+
* The well-known symbol `Symbol.toStringTag` used by `Object.prototype.toString()`.
|
|
1581
|
+
* Returns `'ControlFlow'` so that `Object.prototype.toString.call(flow)` produces `'[object ControlFlow]'`.
|
|
1582
|
+
*
|
|
1583
|
+
* This enables reliable type identification even across different execution contexts (e.g., iframes, different module instances).
|
|
1584
|
+
*
|
|
1585
|
+
* @example
|
|
1586
|
+
* ```ts
|
|
1587
|
+
* const x = Break(5);
|
|
1588
|
+
* console.log(Object.prototype.toString.call(x)); // '[object ControlFlow]'
|
|
1589
|
+
* ```
|
|
1590
|
+
*
|
|
1591
|
+
* @internal
|
|
1592
|
+
*/
|
|
1593
|
+
readonly [Symbol.toStringTag]: 'ControlFlow';
|
|
1594
|
+
/**
|
|
1595
|
+
* A unique symbol property used to identify the variant of this `ControlFlow`.
|
|
1596
|
+
* Returns `'Break'` if the ControlFlow signals early exit, or `'Continue'` if it signals to proceed as normal.
|
|
1597
|
+
*
|
|
1598
|
+
* This is used internally by the `isControlFlow` utility function to verify that an object is a valid `ControlFlow` instance,
|
|
1599
|
+
* and to distinguish between `Break` and `Continue` variants without calling methods.
|
|
1600
|
+
*
|
|
1601
|
+
* Note: The symbol itself is not exported as part of the public API.
|
|
1602
|
+
* Use the `isControlFlow` utility function or the `isBreak()`/`isContinue()` methods for type checking.
|
|
1603
|
+
*
|
|
1604
|
+
* @internal
|
|
1605
|
+
*/
|
|
1606
|
+
readonly [ControlFlowKindSymbol]: 'Break' | 'Continue';
|
|
1607
|
+
/**
|
|
1608
|
+
* Returns `true` if this is a `Break` variant.
|
|
1609
|
+
*
|
|
1610
|
+
* @example
|
|
1611
|
+
* ```ts
|
|
1612
|
+
* console.log(Break(3).isBreak()); // true
|
|
1613
|
+
* console.log(Continue().isBreak()); // false
|
|
1614
|
+
* ```
|
|
1615
|
+
*/
|
|
1616
|
+
isBreak(): boolean;
|
|
1617
|
+
/**
|
|
1618
|
+
* Returns `true` if this is a `Continue` variant.
|
|
1619
|
+
*
|
|
1620
|
+
* @example
|
|
1621
|
+
* ```ts
|
|
1622
|
+
* console.log(Continue().isContinue()); // true
|
|
1623
|
+
* console.log(Break(3).isContinue()); // false
|
|
1624
|
+
* ```
|
|
1625
|
+
*/
|
|
1626
|
+
isContinue(): boolean;
|
|
1627
|
+
/**
|
|
1628
|
+
* Converts the `ControlFlow` into an `Option` which is `Some` if the
|
|
1629
|
+
* `ControlFlow` was `Break` and `None` otherwise.
|
|
1630
|
+
*
|
|
1631
|
+
* @returns `Some(value)` if `Break`, `None` if `Continue`.
|
|
1632
|
+
*
|
|
1633
|
+
* @example
|
|
1634
|
+
* ```ts
|
|
1635
|
+
* console.log(Break(3).breakValue()); // Some(3)
|
|
1636
|
+
* console.log(Continue().breakValue()); // None
|
|
1637
|
+
* ```
|
|
1638
|
+
*/
|
|
1639
|
+
breakValue(): Option<B>;
|
|
1640
|
+
/**
|
|
1641
|
+
* Converts the `ControlFlow` into an `Option` which is `Some` if the
|
|
1642
|
+
* `ControlFlow` was `Continue` and `None` otherwise.
|
|
1643
|
+
*
|
|
1644
|
+
* @returns `Some(value)` if `Continue`, `None` if `Break`.
|
|
1645
|
+
*
|
|
1646
|
+
* @example
|
|
1647
|
+
* ```ts
|
|
1648
|
+
* console.log(Continue(5).continueValue()); // Some(5)
|
|
1649
|
+
* console.log(Break(3).continueValue()); // None
|
|
1650
|
+
* ```
|
|
1651
|
+
*/
|
|
1652
|
+
continueValue(): Option<C>;
|
|
1653
|
+
/**
|
|
1654
|
+
* Maps `ControlFlow<B, C>` to `ControlFlow<T, C>` by applying a function
|
|
1655
|
+
* to the break value in case it exists.
|
|
1656
|
+
*
|
|
1657
|
+
* @typeParam T - The type of the new break value.
|
|
1658
|
+
* @param fn - A function to apply to the break value.
|
|
1659
|
+
* @returns A new `ControlFlow` with the mapped break value.
|
|
1660
|
+
*
|
|
1661
|
+
* @example
|
|
1662
|
+
* ```ts
|
|
1663
|
+
* const flow = Break(3);
|
|
1664
|
+
* console.log(flow.mapBreak(v => v * 2).breakValue()); // Some(6)
|
|
1665
|
+
* ```
|
|
1666
|
+
*/
|
|
1667
|
+
mapBreak<T>(fn: (value: B) => T): ControlFlow<T, C>;
|
|
1668
|
+
/**
|
|
1669
|
+
* Maps `ControlFlow<B, C>` to `ControlFlow<B, T>` by applying a function
|
|
1670
|
+
* to the continue value in case it exists.
|
|
1671
|
+
*
|
|
1672
|
+
* @typeParam T - The type of the new continue value.
|
|
1673
|
+
* @param fn - A function to apply to the continue value.
|
|
1674
|
+
* @returns A new `ControlFlow` with the mapped continue value.
|
|
1675
|
+
*
|
|
1676
|
+
* @example
|
|
1677
|
+
* ```ts
|
|
1678
|
+
* const flow = Continue(5);
|
|
1679
|
+
* console.log(flow.mapContinue(v => v * 2).continueValue()); // Some(10)
|
|
1680
|
+
* ```
|
|
1681
|
+
*/
|
|
1682
|
+
mapContinue<T>(fn: (value: C) => T): ControlFlow<B, T>;
|
|
1683
|
+
/**
|
|
1684
|
+
* Converts the `ControlFlow` into a `Result` which is `Ok` if the
|
|
1685
|
+
* `ControlFlow` was `Break` and `Err` otherwise.
|
|
1686
|
+
*
|
|
1687
|
+
* @returns `Ok(breakValue)` if `Break`, `Err(continueValue)` if `Continue`.
|
|
1688
|
+
*
|
|
1689
|
+
* @example
|
|
1690
|
+
* ```ts
|
|
1691
|
+
* console.log(Break(3).breakOk()); // Ok(3)
|
|
1692
|
+
* console.log(Continue('still going').breakOk()); // Err('still going')
|
|
1693
|
+
* ```
|
|
1694
|
+
*/
|
|
1695
|
+
breakOk(): Result<B, C>;
|
|
1696
|
+
/**
|
|
1697
|
+
* Converts the `ControlFlow` into a `Result` which is `Ok` if the
|
|
1698
|
+
* `ControlFlow` was `Continue` and `Err` otherwise.
|
|
1699
|
+
*
|
|
1700
|
+
* @returns `Ok(continueValue)` if `Continue`, `Err(breakValue)` if `Break`.
|
|
1701
|
+
*
|
|
1702
|
+
* @example
|
|
1703
|
+
* ```ts
|
|
1704
|
+
* console.log(Continue(5).continueOk()); // Ok(5)
|
|
1705
|
+
* console.log(Break('stopped').continueOk()); // Err('stopped')
|
|
1706
|
+
* ```
|
|
1707
|
+
*/
|
|
1708
|
+
continueOk(): Result<C, B>;
|
|
1709
|
+
/**
|
|
1710
|
+
* Custom `toString` implementation that uses the `ControlFlow`'s contained value.
|
|
1711
|
+
* @example
|
|
1712
|
+
* ```ts
|
|
1713
|
+
* console.log(Break(5).toString()); // 'Break(5)'
|
|
1714
|
+
* console.log(Continue('ok').toString()); // 'Continue(ok)'
|
|
1715
|
+
* ```
|
|
1716
|
+
*/
|
|
1717
|
+
toString(): string;
|
|
1718
|
+
}
|
|
1719
|
+
/**
|
|
1720
|
+
* Creates a `Break` variant of `ControlFlow`.
|
|
1721
|
+
*
|
|
1722
|
+
* Use this to signal that an operation should exit early with the given value.
|
|
1723
|
+
*
|
|
1724
|
+
* @typeParam B - The type of the break value.
|
|
1725
|
+
* @typeParam C - The type of the continue value (defaults to `void` when a value is provided).
|
|
1726
|
+
* @param value - The value to return on break.
|
|
1727
|
+
* @returns A `ControlFlow` in the `Break` state.
|
|
1728
|
+
*
|
|
1729
|
+
* @example
|
|
1730
|
+
* ```ts
|
|
1731
|
+
* const flow = Break('found it');
|
|
1732
|
+
* console.log(flow.isBreak()); // true
|
|
1733
|
+
* console.log(flow.breakValue().unwrap()); // 'found it'
|
|
1734
|
+
*
|
|
1735
|
+
* const voidFlow = Break();
|
|
1736
|
+
* console.log(voidFlow.isBreak()); // true
|
|
1737
|
+
* ```
|
|
1738
|
+
*/
|
|
1739
|
+
declare function Break<B, C = never>(value: B): ControlFlow<B, C>;
|
|
1740
|
+
/**
|
|
1741
|
+
* Creates a `Break` variant of `ControlFlow` with no value.
|
|
1742
|
+
* This overload is used when the operation exits early but doesn't produce a meaningful value.
|
|
1743
|
+
*
|
|
1744
|
+
* @typeParam C - The type of the continue value (allows type specification when chaining with Continue).
|
|
1745
|
+
* @returns A `ControlFlow<void, C>` in the `Break` state.
|
|
1746
|
+
*
|
|
1747
|
+
* @example
|
|
1748
|
+
* ```ts
|
|
1749
|
+
* const voidFlow = Break();
|
|
1750
|
+
* console.log(voidFlow.isBreak()); // true
|
|
1751
|
+
* console.log(voidFlow.breakValue()); // Some(undefined)
|
|
1752
|
+
*
|
|
1753
|
+
* // With explicit type parameter
|
|
1754
|
+
* const typedFlow = Break<number>(); // ControlFlow<void, number>
|
|
1755
|
+
* ```
|
|
1756
|
+
*/
|
|
1757
|
+
declare function Break<C = never>(): ControlFlow<void, C>;
|
|
1758
|
+
/**
|
|
1759
|
+
* Creates a `Continue` variant of `ControlFlow`.
|
|
1760
|
+
*
|
|
1761
|
+
* Use this to signal that an operation should continue as normal.
|
|
1762
|
+
*
|
|
1763
|
+
* @typeParam B - The type of the break value (defaults to `void` when a value is provided).
|
|
1764
|
+
* @typeParam C - The type of the continue value.
|
|
1765
|
+
* @param value - The value to carry forward (optional, defaults to `undefined`).
|
|
1766
|
+
* @returns A `ControlFlow` in the `Continue` state.
|
|
1767
|
+
*
|
|
1768
|
+
* @example
|
|
1769
|
+
* ```ts
|
|
1770
|
+
* const flow = Continue();
|
|
1771
|
+
* console.log(flow.isContinue()); // true
|
|
1772
|
+
*
|
|
1773
|
+
* const flowWithValue = Continue(42);
|
|
1774
|
+
* console.log(flowWithValue.continueValue().unwrap()); // 42
|
|
1775
|
+
* ```
|
|
1776
|
+
*/
|
|
1777
|
+
declare function Continue<B = never, C = void>(value: C): ControlFlow<B, C>;
|
|
1778
|
+
/**
|
|
1779
|
+
* Creates a `Continue` variant of `ControlFlow` with no value.
|
|
1780
|
+
* This overload is used when the operation continues but doesn't carry a meaningful value.
|
|
1781
|
+
*
|
|
1782
|
+
* @typeParam B - The type of the break value (allows type specification when chaining with Break).
|
|
1783
|
+
* @returns A `ControlFlow<B, void>` in the `Continue` state.
|
|
1784
|
+
*
|
|
1785
|
+
* @example
|
|
1786
|
+
* ```ts
|
|
1787
|
+
* const voidFlow = Continue();
|
|
1788
|
+
* console.log(voidFlow.isContinue()); // true
|
|
1789
|
+
* console.log(voidFlow.continueValue()); // Some(undefined)
|
|
1790
|
+
*
|
|
1791
|
+
* // With explicit type parameter
|
|
1792
|
+
* const typedFlow = Continue<string>(); // ControlFlow<string, void>
|
|
1793
|
+
* ```
|
|
1794
|
+
*/
|
|
1795
|
+
declare function Continue<B = never>(): ControlFlow<B, void>;
|
|
1796
|
+
|
|
1797
|
+
/**
|
|
1798
|
+
* @fileoverview
|
|
1799
|
+
* Type guard utilities for checking if values are `ControlFlow` types.
|
|
1800
|
+
*
|
|
1801
|
+
* These functions provide runtime type checking capabilities for the ControlFlow type.
|
|
1802
|
+
*/
|
|
1803
|
+
|
|
1804
|
+
/**
|
|
1805
|
+
* Checks if a value is a `ControlFlow`.
|
|
1806
|
+
*
|
|
1807
|
+
* @typeParam B - The expected type of the break value contained within the `ControlFlow`.
|
|
1808
|
+
* @typeParam C - The expected type of the continue value contained within the `ControlFlow`.
|
|
1809
|
+
* @param cf - The value to be checked as a `ControlFlow`.
|
|
1810
|
+
* @returns `true` if the value is a `ControlFlow`, otherwise `false`.
|
|
1811
|
+
* @example
|
|
1812
|
+
* ```ts
|
|
1813
|
+
* const x = Break(5);
|
|
1814
|
+
* console.log(isControlFlow(x)); // true
|
|
1815
|
+
* console.log(isControlFlow(null)); // false
|
|
1816
|
+
* console.log(isControlFlow({ isBreak: () => true })); // false
|
|
1817
|
+
* ```
|
|
1818
|
+
*/
|
|
1819
|
+
declare function isControlFlow<B, C>(cf: unknown): cf is ControlFlow<B, C>;
|
|
1820
|
+
|
|
1821
|
+
/**
|
|
1822
|
+
* @fileoverview
|
|
1823
|
+
* Rust-inspired [LazyLock](https://doc.rust-lang.org/std/sync/struct.LazyLock.html) for lazy initialization.
|
|
1824
|
+
*
|
|
1825
|
+
* `Lazy<T>` is a value which is initialized on the first access. Unlike `Once<T>`,
|
|
1826
|
+
* the initialization function is provided at construction time.
|
|
1827
|
+
*/
|
|
1828
|
+
|
|
1829
|
+
/**
|
|
1830
|
+
* A value which is initialized on the first access.
|
|
1831
|
+
*
|
|
1832
|
+
* This is a lazily evaluated value. The initialization function is provided
|
|
1833
|
+
* at construction time and executed on first access. Subsequent accesses
|
|
1834
|
+
* return the cached value.
|
|
1835
|
+
*
|
|
1836
|
+
* Unlike `Once<T>`, which allows setting values manually or with different
|
|
1837
|
+
* initializers, `Lazy<T>` binds the initializer at creation time.
|
|
1838
|
+
*
|
|
1839
|
+
* @typeParam T - The type of the value stored.
|
|
1840
|
+
*
|
|
1841
|
+
* @example
|
|
1842
|
+
* ```ts
|
|
1843
|
+
* const expensive = Lazy(() => {
|
|
1844
|
+
* console.log('Computing...');
|
|
1845
|
+
* return heavyComputation();
|
|
1846
|
+
* });
|
|
1847
|
+
*
|
|
1848
|
+
* // Nothing computed yet
|
|
1849
|
+
* console.log(expensive.isInitialized()); // false
|
|
1850
|
+
*
|
|
1851
|
+
* // First access triggers computation
|
|
1852
|
+
* const value = expensive.force(); // logs "Computing..."
|
|
1853
|
+
*
|
|
1854
|
+
* // Subsequent access returns cached value
|
|
1855
|
+
* const same = expensive.force(); // no log, returns cached value
|
|
1856
|
+
* ```
|
|
1857
|
+
*/
|
|
1858
|
+
interface Lazy<T> {
|
|
1859
|
+
/**
|
|
1860
|
+
* The well-known symbol `Symbol.toStringTag` used by `Object.prototype.toString()`.
|
|
1861
|
+
* Returns `'Lazy'` so that `Object.prototype.toString.call(lazy)` produces `'[object Lazy]'`.
|
|
1862
|
+
*
|
|
1863
|
+
* @internal
|
|
1864
|
+
*/
|
|
1865
|
+
readonly [Symbol.toStringTag]: 'Lazy';
|
|
1866
|
+
/**
|
|
1867
|
+
* Forces the evaluation of this lazy value and returns the result.
|
|
1868
|
+
*
|
|
1869
|
+
* If the value has already been initialized, returns the cached value.
|
|
1870
|
+
* Otherwise, executes the initialization function, caches the result,
|
|
1871
|
+
* and returns it.
|
|
1872
|
+
*
|
|
1873
|
+
* @returns The initialized value.
|
|
1874
|
+
*
|
|
1875
|
+
* @example
|
|
1876
|
+
* ```ts
|
|
1877
|
+
* const lazy = Lazy(() => 42);
|
|
1878
|
+
* console.log(lazy.force()); // 42
|
|
1879
|
+
* console.log(lazy.force()); // 42 (cached)
|
|
1880
|
+
* ```
|
|
1881
|
+
*/
|
|
1882
|
+
force(): T;
|
|
1883
|
+
/**
|
|
1884
|
+
* Gets the value if it has been initialized.
|
|
1885
|
+
*
|
|
1886
|
+
* Unlike `force()`, this does not trigger initialization.
|
|
1887
|
+
*
|
|
1888
|
+
* @returns `Some(value)` if initialized, `None` otherwise.
|
|
1889
|
+
*
|
|
1890
|
+
* @example
|
|
1891
|
+
* ```ts
|
|
1892
|
+
* const lazy = Lazy(() => 42);
|
|
1893
|
+
* console.log(lazy.get()); // None
|
|
1894
|
+
*
|
|
1895
|
+
* lazy.force();
|
|
1896
|
+
* console.log(lazy.get()); // Some(42)
|
|
1897
|
+
* ```
|
|
1898
|
+
*/
|
|
1899
|
+
get(): Option<T>;
|
|
1900
|
+
/**
|
|
1901
|
+
* Returns `true` if the value has been initialized.
|
|
1902
|
+
*
|
|
1903
|
+
* @example
|
|
1904
|
+
* ```ts
|
|
1905
|
+
* const lazy = Lazy(() => 42);
|
|
1906
|
+
* console.log(lazy.isInitialized()); // false
|
|
1907
|
+
*
|
|
1908
|
+
* lazy.force();
|
|
1909
|
+
* console.log(lazy.isInitialized()); // true
|
|
1910
|
+
* ```
|
|
1911
|
+
*/
|
|
1912
|
+
isInitialized(): boolean;
|
|
1913
|
+
/**
|
|
1914
|
+
* Custom `toString` implementation.
|
|
1915
|
+
* @example
|
|
1916
|
+
* ```ts
|
|
1917
|
+
* const lazy = Lazy(() => 42);
|
|
1918
|
+
* console.log(lazy.toString()); // 'Lazy(<uninitialized>)'
|
|
1919
|
+
*
|
|
1920
|
+
* lazy.force();
|
|
1921
|
+
* console.log(lazy.toString()); // 'Lazy(42)'
|
|
1922
|
+
* ```
|
|
1923
|
+
*/
|
|
1924
|
+
toString(): string;
|
|
1925
|
+
}
|
|
1926
|
+
/**
|
|
1927
|
+
* Creates a new `Lazy<T>` with the given synchronous initialization function.
|
|
1928
|
+
*
|
|
1929
|
+
* The function is called at most once, on first access via `force()`.
|
|
1930
|
+
*
|
|
1931
|
+
* @typeParam T - The type of value to store.
|
|
1932
|
+
* @param fn - The initialization function that produces the value.
|
|
1933
|
+
* @returns A new `Lazy<T>` instance.
|
|
1934
|
+
*
|
|
1935
|
+
* @example
|
|
1936
|
+
* ```ts
|
|
1937
|
+
* // Basic usage
|
|
1938
|
+
* const lazy = Lazy(() => {
|
|
1939
|
+
* console.log('Initializing');
|
|
1940
|
+
* return 42;
|
|
1941
|
+
* });
|
|
1942
|
+
*
|
|
1943
|
+
* console.log(lazy.isInitialized()); // false
|
|
1944
|
+
* console.log(lazy.force()); // logs "Initializing", returns 42
|
|
1945
|
+
* console.log(lazy.isInitialized()); // true
|
|
1946
|
+
* console.log(lazy.force()); // returns 42 (no log)
|
|
1947
|
+
* ```
|
|
1948
|
+
*
|
|
1949
|
+
* @example
|
|
1950
|
+
* ```ts
|
|
1951
|
+
* // Lazy singleton pattern
|
|
1952
|
+
* const logger = Lazy(() => new Logger('app'));
|
|
1953
|
+
*
|
|
1954
|
+
* function getLogger(): Logger {
|
|
1955
|
+
* return logger.force();
|
|
1956
|
+
* }
|
|
1957
|
+
* ```
|
|
1958
|
+
*
|
|
1959
|
+
* @example
|
|
1960
|
+
* ```ts
|
|
1961
|
+
* // Expensive computation
|
|
1962
|
+
* const fibonacci = Lazy(() => {
|
|
1963
|
+
* function fib(n: number): number {
|
|
1964
|
+
* if (n <= 1) return n;
|
|
1965
|
+
* return fib(n - 1) + fib(n - 2);
|
|
1966
|
+
* }
|
|
1967
|
+
* return fib(40); // Only computed once
|
|
1968
|
+
* });
|
|
1969
|
+
* ```
|
|
1970
|
+
*/
|
|
1971
|
+
declare function Lazy<T>(fn: () => T): Lazy<T>;
|
|
1972
|
+
/**
|
|
1973
|
+
* A value which is initialized asynchronously on the first access.
|
|
1974
|
+
*
|
|
1975
|
+
* Similar to `Lazy<T>`, but the initialization function is async.
|
|
1976
|
+
* If multiple calls to `force()` occur concurrently before initialization
|
|
1977
|
+
* completes, only one initialization will run.
|
|
1978
|
+
*
|
|
1979
|
+
* @typeParam T - The type of the value stored.
|
|
1980
|
+
*
|
|
1981
|
+
* @example
|
|
1982
|
+
* ```ts
|
|
1983
|
+
* const db = LazyAsync(async () => {
|
|
1984
|
+
* console.log('Connecting...');
|
|
1985
|
+
* return await Database.connect(url);
|
|
1986
|
+
* });
|
|
1987
|
+
*
|
|
1988
|
+
* // Multiple concurrent accesses - only one connection
|
|
1989
|
+
* const [db1, db2] = await Promise.all([
|
|
1990
|
+
* db.force(),
|
|
1991
|
+
* db.force(),
|
|
1992
|
+
* ]);
|
|
1993
|
+
* // db1 === db2
|
|
1994
|
+
* ```
|
|
1995
|
+
*/
|
|
1996
|
+
interface LazyAsync<T> {
|
|
1997
|
+
/**
|
|
1998
|
+
* The well-known symbol `Symbol.toStringTag` used by `Object.prototype.toString()`.
|
|
1999
|
+
* Returns `'LazyAsync'` so that `Object.prototype.toString.call(lazy)` produces `'[object LazyAsync]'`.
|
|
2000
|
+
*
|
|
2001
|
+
* @internal
|
|
2002
|
+
*/
|
|
2003
|
+
readonly [Symbol.toStringTag]: 'LazyAsync';
|
|
2004
|
+
/**
|
|
2005
|
+
* Forces the evaluation of this lazy value and returns a promise to the result.
|
|
2006
|
+
*
|
|
2007
|
+
* If the value has already been initialized, returns the cached value.
|
|
2008
|
+
* If initialization is in progress, waits for it to complete.
|
|
2009
|
+
* Otherwise, starts initialization.
|
|
2010
|
+
*
|
|
2011
|
+
* @returns A promise that resolves to the initialized value.
|
|
2012
|
+
*
|
|
2013
|
+
* @example
|
|
2014
|
+
* ```ts
|
|
2015
|
+
* const lazy = LazyAsync(async () => {
|
|
2016
|
+
* await delay(100);
|
|
2017
|
+
* return 42;
|
|
2018
|
+
* });
|
|
2019
|
+
* console.log(await lazy.force()); // 42
|
|
2020
|
+
* ```
|
|
2021
|
+
*/
|
|
2022
|
+
force(): Promise<T>;
|
|
2023
|
+
/**
|
|
2024
|
+
* Gets the value if it has been initialized.
|
|
2025
|
+
*
|
|
2026
|
+
* Unlike `force()`, this does not trigger initialization.
|
|
2027
|
+
*
|
|
2028
|
+
* @returns `Some(value)` if initialized, `None` otherwise.
|
|
2029
|
+
*
|
|
2030
|
+
* @example
|
|
2031
|
+
* ```ts
|
|
2032
|
+
* const lazy = LazyAsync(async () => 42);
|
|
2033
|
+
* console.log(lazy.get()); // None
|
|
2034
|
+
*
|
|
2035
|
+
* await lazy.force();
|
|
2036
|
+
* console.log(lazy.get()); // Some(42)
|
|
2037
|
+
* ```
|
|
2038
|
+
*/
|
|
2039
|
+
get(): Option<T>;
|
|
2040
|
+
/**
|
|
2041
|
+
* Returns `true` if the value has been initialized.
|
|
2042
|
+
*
|
|
2043
|
+
* Note: Returns `false` while initialization is in progress.
|
|
2044
|
+
*
|
|
2045
|
+
* @example
|
|
2046
|
+
* ```ts
|
|
2047
|
+
* const lazy = LazyAsync(async () => 42);
|
|
2048
|
+
* console.log(lazy.isInitialized()); // false
|
|
2049
|
+
*
|
|
2050
|
+
* await lazy.force();
|
|
2051
|
+
* console.log(lazy.isInitialized()); // true
|
|
2052
|
+
* ```
|
|
2053
|
+
*/
|
|
2054
|
+
isInitialized(): boolean;
|
|
2055
|
+
/**
|
|
2056
|
+
* Custom `toString` implementation.
|
|
2057
|
+
* @example
|
|
2058
|
+
* ```ts
|
|
2059
|
+
* const lazy = LazyAsync(async () => 42);
|
|
2060
|
+
* console.log(lazy.toString()); // 'LazyAsync(<uninitialized>)'
|
|
2061
|
+
*
|
|
2062
|
+
* await lazy.force();
|
|
2063
|
+
* console.log(lazy.toString()); // 'LazyAsync(42)'
|
|
2064
|
+
* ```
|
|
2065
|
+
*/
|
|
2066
|
+
toString(): string;
|
|
2067
|
+
}
|
|
2068
|
+
/**
|
|
2069
|
+
* Creates a new `LazyAsync<T>` with the given async initialization function.
|
|
2070
|
+
*
|
|
2071
|
+
* The function is called at most once, on first access via `force()`.
|
|
2072
|
+
* Concurrent calls to `force()` before initialization completes will
|
|
2073
|
+
* wait for the single initialization to finish.
|
|
2074
|
+
*
|
|
2075
|
+
* @typeParam T - The type of value to store.
|
|
2076
|
+
* @param fn - The async initialization function that produces the value.
|
|
2077
|
+
* @returns A new `LazyAsync<T>` instance.
|
|
2078
|
+
*
|
|
2079
|
+
* @example
|
|
2080
|
+
* ```ts
|
|
2081
|
+
* // Basic usage
|
|
2082
|
+
* const lazy = LazyAsync(async () => {
|
|
2083
|
+
* const response = await fetch('/api/data');
|
|
2084
|
+
* return await response.json();
|
|
2085
|
+
* });
|
|
2086
|
+
*
|
|
2087
|
+
* const data = await lazy.force();
|
|
2088
|
+
* ```
|
|
2089
|
+
*
|
|
2090
|
+
* @example
|
|
2091
|
+
* ```ts
|
|
2092
|
+
* // Database connection singleton
|
|
2093
|
+
* const db = LazyAsync(async () => {
|
|
2094
|
+
* console.log('Connecting to database...');
|
|
2095
|
+
* return await Database.connect(connectionString);
|
|
2096
|
+
* });
|
|
2097
|
+
*
|
|
2098
|
+
* async function getDb(): Promise<Database> {
|
|
2099
|
+
* return await db.force();
|
|
2100
|
+
* }
|
|
2101
|
+
*
|
|
2102
|
+
* // Multiple calls - connection happens only once
|
|
2103
|
+
* const [db1, db2] = await Promise.all([getDb(), getDb()]);
|
|
2104
|
+
* console.log(db1 === db2); // true
|
|
2105
|
+
* ```
|
|
2106
|
+
*
|
|
2107
|
+
* @example
|
|
2108
|
+
* ```ts
|
|
2109
|
+
* // Configuration loader
|
|
2110
|
+
* const config = LazyAsync(async () => {
|
|
2111
|
+
* const response = await fetch('/api/config');
|
|
2112
|
+
* if (!response.ok) {
|
|
2113
|
+
* throw new Error(`Failed to load config: ${response.status}`);
|
|
2114
|
+
* }
|
|
2115
|
+
* return await response.json() as Config;
|
|
2116
|
+
* });
|
|
2117
|
+
*
|
|
2118
|
+
* // Used throughout the app
|
|
2119
|
+
* async function getApiEndpoint(): Promise<string> {
|
|
2120
|
+
* const cfg = await config.force();
|
|
2121
|
+
* return cfg.apiEndpoint;
|
|
2122
|
+
* }
|
|
2123
|
+
* ```
|
|
2124
|
+
*/
|
|
2125
|
+
declare function LazyAsync<T>(fn: () => Promise<T>): LazyAsync<T>;
|
|
2126
|
+
|
|
2127
|
+
/**
|
|
2128
|
+
* @fileoverview
|
|
2129
|
+
* Rust-inspired [Mutex](https://doc.rust-lang.org/std/sync/struct.Mutex.html) for async mutual exclusion.
|
|
2130
|
+
*
|
|
2131
|
+
* In JavaScript's single-threaded environment, `Mutex<T>` is used to serialize
|
|
2132
|
+
* async operations, ensuring only one async task accesses the protected resource at a time.
|
|
2133
|
+
*/
|
|
2134
|
+
|
|
2135
|
+
/**
|
|
2136
|
+
* A guard that provides access to the mutex-protected value.
|
|
2137
|
+
*
|
|
2138
|
+
* The guard must be released after use by calling `unlock()`.
|
|
2139
|
+
* Failure to unlock will cause deadlock for subsequent lock attempts.
|
|
2140
|
+
*
|
|
2141
|
+
* @typeParam T - The type of the protected value.
|
|
2142
|
+
*/
|
|
2143
|
+
interface MutexGuard<T> {
|
|
2144
|
+
/**
|
|
2145
|
+
* The well-known symbol `Symbol.toStringTag` used by `Object.prototype.toString()`.
|
|
2146
|
+
* Returns `'MutexGuard'` so that `Object.prototype.toString.call(guard)` produces `'[object MutexGuard]'`.
|
|
2147
|
+
*
|
|
2148
|
+
* @internal
|
|
2149
|
+
*/
|
|
2150
|
+
readonly [Symbol.toStringTag]: 'MutexGuard';
|
|
2151
|
+
/**
|
|
2152
|
+
* The protected value. Can be read or modified while the guard is held.
|
|
2153
|
+
*/
|
|
2154
|
+
value: T;
|
|
2155
|
+
/**
|
|
2156
|
+
* Releases the lock, allowing other waiters to acquire it.
|
|
2157
|
+
*
|
|
2158
|
+
* Must be called when done with the protected value.
|
|
2159
|
+
* After calling `unlock()`, the guard should not be used.
|
|
2160
|
+
*
|
|
2161
|
+
* @example
|
|
2162
|
+
* ```ts
|
|
2163
|
+
* const guard = await mutex.lock();
|
|
2164
|
+
* try {
|
|
2165
|
+
* guard.value.push('item');
|
|
2166
|
+
* } finally {
|
|
2167
|
+
* guard.unlock();
|
|
2168
|
+
* }
|
|
2169
|
+
* ```
|
|
2170
|
+
*/
|
|
2171
|
+
unlock(): void;
|
|
2172
|
+
/**
|
|
2173
|
+
* Custom `toString` implementation.
|
|
2174
|
+
* @example
|
|
2175
|
+
* ```ts
|
|
2176
|
+
* const guard = await mutex.lock();
|
|
2177
|
+
* console.log(guard.toString()); // 'MutexGuard(42)'
|
|
2178
|
+
* ```
|
|
2179
|
+
*/
|
|
2180
|
+
toString(): string;
|
|
2181
|
+
}
|
|
2182
|
+
/**
|
|
2183
|
+
* An async mutual exclusion primitive for protecting shared data.
|
|
2184
|
+
*
|
|
2185
|
+
* This mutex provides exclusive access to the contained value, ensuring
|
|
2186
|
+
* that only one async operation can access it at a time. This is useful
|
|
2187
|
+
* for preventing race conditions in async code.
|
|
2188
|
+
*
|
|
2189
|
+
* Unlike Rust's Mutex which is for multi-threading, this JavaScript version
|
|
2190
|
+
* serializes async operations in the single-threaded event loop.
|
|
2191
|
+
*
|
|
2192
|
+
* @typeParam T - The type of the protected value.
|
|
2193
|
+
*
|
|
2194
|
+
* @example
|
|
2195
|
+
* ```ts
|
|
2196
|
+
* const mutex = Mutex({ balance: 100 });
|
|
2197
|
+
*
|
|
2198
|
+
* // Safe concurrent updates
|
|
2199
|
+
* await Promise.all([
|
|
2200
|
+
* mutex.withLock(async (account) => {
|
|
2201
|
+
* account.balance -= 50;
|
|
2202
|
+
* }),
|
|
2203
|
+
* mutex.withLock(async (account) => {
|
|
2204
|
+
* account.balance += 30;
|
|
2205
|
+
* }),
|
|
2206
|
+
* ]);
|
|
2207
|
+
* ```
|
|
2208
|
+
*/
|
|
2209
|
+
interface Mutex<T> {
|
|
2210
|
+
/**
|
|
2211
|
+
* The well-known symbol `Symbol.toStringTag` used by `Object.prototype.toString()`.
|
|
2212
|
+
* Returns `'Mutex'` so that `Object.prototype.toString.call(mutex)` produces `'[object Mutex]'`.
|
|
2213
|
+
*
|
|
2214
|
+
* @internal
|
|
2215
|
+
*/
|
|
2216
|
+
readonly [Symbol.toStringTag]: 'Mutex';
|
|
2217
|
+
/**
|
|
2218
|
+
* Acquires the lock and executes the callback with the protected value.
|
|
2219
|
+
*
|
|
2220
|
+
* This is the recommended way to use the mutex as it automatically
|
|
2221
|
+
* releases the lock when the callback completes (or throws).
|
|
2222
|
+
*
|
|
2223
|
+
* @typeParam U - The return type of the callback.
|
|
2224
|
+
* @param fn - The callback that receives the protected value.
|
|
2225
|
+
* @returns A promise that resolves to the callback's return value.
|
|
2226
|
+
*
|
|
2227
|
+
* @example
|
|
2228
|
+
* ```ts
|
|
2229
|
+
* const mutex = Mutex<number[]>([]);
|
|
2230
|
+
*
|
|
2231
|
+
* await mutex.withLock(async (arr) => {
|
|
2232
|
+
* arr.push(await fetchItem());
|
|
2233
|
+
* });
|
|
2234
|
+
* ```
|
|
2235
|
+
*/
|
|
2236
|
+
withLock<U>(fn: (value: T) => Promise<U> | U): Promise<U>;
|
|
2237
|
+
/**
|
|
2238
|
+
* Acquires the lock and returns a guard for manual control.
|
|
2239
|
+
*
|
|
2240
|
+
* Use this when you need more control over when to release the lock.
|
|
2241
|
+
* **Important:** Always release the lock in a `finally` block to prevent deadlocks.
|
|
2242
|
+
*
|
|
2243
|
+
* @returns A promise that resolves to a guard providing access to the value.
|
|
2244
|
+
*
|
|
2245
|
+
* @example
|
|
2246
|
+
* ```ts
|
|
2247
|
+
* const guard = await mutex.lock();
|
|
2248
|
+
* try {
|
|
2249
|
+
* // Long-running operation with the protected value
|
|
2250
|
+
* await processData(guard.value);
|
|
2251
|
+
* guard.value = transformedData;
|
|
2252
|
+
* } finally {
|
|
2253
|
+
* guard.unlock();
|
|
2254
|
+
* }
|
|
2255
|
+
* ```
|
|
2256
|
+
*/
|
|
2257
|
+
lock(): Promise<MutexGuard<T>>;
|
|
2258
|
+
/**
|
|
2259
|
+
* Attempts to acquire the lock without waiting.
|
|
2260
|
+
*
|
|
2261
|
+
* Returns immediately with `Some(guard)` if the lock is available,
|
|
2262
|
+
* or `None` if it's currently held by another operation.
|
|
2263
|
+
*
|
|
2264
|
+
* @returns `Some(guard)` if acquired, `None` if locked.
|
|
2265
|
+
*
|
|
2266
|
+
* @example
|
|
2267
|
+
* ```ts
|
|
2268
|
+
* const maybeGuard = mutex.tryLock();
|
|
2269
|
+
* if (maybeGuard.isSome()) {
|
|
2270
|
+
* const guard = maybeGuard.unwrap();
|
|
2271
|
+
* try {
|
|
2272
|
+
* // Use the value
|
|
2273
|
+
* } finally {
|
|
2274
|
+
* guard.unlock();
|
|
2275
|
+
* }
|
|
2276
|
+
* } else {
|
|
2277
|
+
* console.log('Mutex is busy');
|
|
2278
|
+
* }
|
|
2279
|
+
* ```
|
|
2280
|
+
*/
|
|
2281
|
+
tryLock(): Option<MutexGuard<T>>;
|
|
2282
|
+
/**
|
|
2283
|
+
* Returns `true` if the mutex is currently locked.
|
|
2284
|
+
*
|
|
2285
|
+
* Note: This is a snapshot and may change immediately after the call.
|
|
2286
|
+
*
|
|
2287
|
+
* @example
|
|
2288
|
+
* ```ts
|
|
2289
|
+
* console.log(mutex.isLocked()); // false
|
|
2290
|
+
* const guard = await mutex.lock();
|
|
2291
|
+
* console.log(mutex.isLocked()); // true
|
|
2292
|
+
* guard.unlock();
|
|
2293
|
+
* console.log(mutex.isLocked()); // false
|
|
2294
|
+
* ```
|
|
2295
|
+
*/
|
|
2296
|
+
isLocked(): boolean;
|
|
2297
|
+
/**
|
|
2298
|
+
* Custom `toString` implementation.
|
|
2299
|
+
* @example
|
|
2300
|
+
* ```ts
|
|
2301
|
+
* const mutex = Mutex(42);
|
|
2302
|
+
* console.log(mutex.toString()); // 'Mutex(<unlocked>)'
|
|
2303
|
+
*
|
|
2304
|
+
* const guard = await mutex.lock();
|
|
2305
|
+
* console.log(mutex.toString()); // 'Mutex(<locked>)'
|
|
2306
|
+
* ```
|
|
2307
|
+
*/
|
|
2308
|
+
toString(): string;
|
|
2309
|
+
}
|
|
2310
|
+
/**
|
|
2311
|
+
* Creates a new `Mutex<T>` protecting the given value.
|
|
2312
|
+
*
|
|
2313
|
+
* @typeParam T - The type of the protected value.
|
|
2314
|
+
* @param value - The initial value to protect.
|
|
2315
|
+
* @returns A new `Mutex<T>` instance.
|
|
2316
|
+
*
|
|
2317
|
+
* @example
|
|
2318
|
+
* ```ts
|
|
2319
|
+
* // Protect a simple value
|
|
2320
|
+
* const counter = Mutex(0);
|
|
2321
|
+
*
|
|
2322
|
+
* // Protect an object
|
|
2323
|
+
* const state = Mutex({ users: [], lastUpdate: Date.now() });
|
|
2324
|
+
*
|
|
2325
|
+
* // Protect a resource
|
|
2326
|
+
* const db = Mutex(await createConnection());
|
|
2327
|
+
* ```
|
|
2328
|
+
*
|
|
2329
|
+
* @example
|
|
2330
|
+
* ```ts
|
|
2331
|
+
* // Database transaction safety
|
|
2332
|
+
* const connection = Mutex(db);
|
|
2333
|
+
*
|
|
2334
|
+
* async function transfer(from: string, to: string, amount: number) {
|
|
2335
|
+
* await connection.withLock(async (conn) => {
|
|
2336
|
+
* await conn.beginTransaction();
|
|
2337
|
+
* try {
|
|
2338
|
+
* const balance = await conn.query('SELECT balance FROM accounts WHERE id = ?', [from]);
|
|
2339
|
+
* if (balance < amount) {
|
|
2340
|
+
* throw new Error('Insufficient funds');
|
|
2341
|
+
* }
|
|
2342
|
+
* await conn.query('UPDATE accounts SET balance = balance - ? WHERE id = ?', [amount, from]);
|
|
2343
|
+
* await conn.query('UPDATE accounts SET balance = balance + ? WHERE id = ?', [amount, to]);
|
|
2344
|
+
* await conn.commit();
|
|
2345
|
+
* } catch (e) {
|
|
2346
|
+
* await conn.rollback();
|
|
2347
|
+
* throw e;
|
|
2348
|
+
* }
|
|
2349
|
+
* });
|
|
2350
|
+
* }
|
|
2351
|
+
* ```
|
|
2352
|
+
*
|
|
2353
|
+
* @example
|
|
2354
|
+
* ```ts
|
|
2355
|
+
* // Token refresh with mutex
|
|
2356
|
+
* const authState = Mutex({ token: '', expiresAt: 0 });
|
|
2357
|
+
*
|
|
2358
|
+
* async function getToken(): Promise<string> {
|
|
2359
|
+
* return await authState.withLock(async (state) => {
|
|
2360
|
+
* if (Date.now() > state.expiresAt) {
|
|
2361
|
+
* const response = await fetch('/api/refresh');
|
|
2362
|
+
* const data = await response.json();
|
|
2363
|
+
* state.token = data.token;
|
|
2364
|
+
* state.expiresAt = Date.now() + data.expiresIn * 1000;
|
|
2365
|
+
* }
|
|
2366
|
+
* return state.token;
|
|
2367
|
+
* });
|
|
2368
|
+
* }
|
|
2369
|
+
* ```
|
|
2370
|
+
*
|
|
2371
|
+
* @example
|
|
2372
|
+
* ```ts
|
|
2373
|
+
* // File write serialization
|
|
2374
|
+
* const fileLock = Mutex('/path/to/file.json');
|
|
2375
|
+
*
|
|
2376
|
+
* async function appendToFile(data: string) {
|
|
2377
|
+
* await fileLock.withLock(async (path) => {
|
|
2378
|
+
* const content = await fs.readFile(path, 'utf-8');
|
|
2379
|
+
* const json = JSON.parse(content);
|
|
2380
|
+
* json.entries.push(data);
|
|
2381
|
+
* await fs.writeFile(path, JSON.stringify(json, null, 2));
|
|
2382
|
+
* });
|
|
2383
|
+
* }
|
|
2384
|
+
* ```
|
|
2385
|
+
*/
|
|
2386
|
+
declare function Mutex<T>(value: T): Mutex<T>;
|
|
2387
|
+
|
|
2388
|
+
/**
|
|
2389
|
+
* @fileoverview
|
|
2390
|
+
* Rust-inspired [OnceLock](https://doc.rust-lang.org/std/sync/struct.OnceLock.html) for one-time initialization.
|
|
2391
|
+
*
|
|
2392
|
+
* `Once<T>` is a container which can be written to only once. It provides safe access
|
|
2393
|
+
* to lazily initialized data, supporting both sync and async initialization.
|
|
2394
|
+
*/
|
|
2395
|
+
|
|
2396
|
+
/**
|
|
2397
|
+
* A container which can be written to only once.
|
|
2398
|
+
*
|
|
2399
|
+
* This is useful for lazy initialization of global data or expensive computations
|
|
2400
|
+
* that should only happen once. Supports both synchronous and asynchronous
|
|
2401
|
+
* initialization functions via separate methods.
|
|
2402
|
+
*
|
|
2403
|
+
* @typeParam T - The type of the value stored.
|
|
2404
|
+
*
|
|
2405
|
+
* @example
|
|
2406
|
+
* ```ts
|
|
2407
|
+
* const once = Once<number>();
|
|
2408
|
+
*
|
|
2409
|
+
* // Set value (only works once)
|
|
2410
|
+
* once.set(42); // Ok(undefined)
|
|
2411
|
+
* once.set(100); // Err(100) - already set
|
|
2412
|
+
*
|
|
2413
|
+
* // Get value
|
|
2414
|
+
* console.log(once.get()); // Some(42)
|
|
2415
|
+
* ```
|
|
2416
|
+
*
|
|
2417
|
+
* @example
|
|
2418
|
+
* ```ts
|
|
2419
|
+
* // Sync lazy initialization
|
|
2420
|
+
* const config = Once<Config>();
|
|
2421
|
+
* const cfg = config.getOrInit(() => loadConfigFromFile());
|
|
2422
|
+
* ```
|
|
2423
|
+
*
|
|
2424
|
+
* @example
|
|
2425
|
+
* ```ts
|
|
2426
|
+
* // Async lazy initialization
|
|
2427
|
+
* const db = Once<Database>();
|
|
2428
|
+
* const conn = await db.getOrInitAsync(async () => Database.connect(url));
|
|
2429
|
+
* ```
|
|
2430
|
+
*/
|
|
2431
|
+
interface Once<T> {
|
|
2432
|
+
/**
|
|
2433
|
+
* The well-known symbol `Symbol.toStringTag` used by `Object.prototype.toString()`.
|
|
2434
|
+
* Returns `'Once'` so that `Object.prototype.toString.call(once)` produces `'[object Once]'`.
|
|
2435
|
+
*
|
|
2436
|
+
* @internal
|
|
2437
|
+
*/
|
|
2438
|
+
readonly [Symbol.toStringTag]: 'Once';
|
|
2439
|
+
/**
|
|
2440
|
+
* Gets the reference to the underlying value.
|
|
2441
|
+
*
|
|
2442
|
+
* @returns `Some(value)` if initialized, `None` otherwise.
|
|
2443
|
+
*
|
|
2444
|
+
* @example
|
|
2445
|
+
* ```ts
|
|
2446
|
+
* const once = Once<number>();
|
|
2447
|
+
* console.log(once.get()); // None
|
|
2448
|
+
*
|
|
2449
|
+
* once.set(42);
|
|
2450
|
+
* console.log(once.get()); // Some(42)
|
|
2451
|
+
* ```
|
|
2452
|
+
*/
|
|
2453
|
+
get(): Option<T>;
|
|
2454
|
+
/**
|
|
2455
|
+
* Sets the contents to `value`.
|
|
2456
|
+
*
|
|
2457
|
+
* @param value - The value to store.
|
|
2458
|
+
* @returns `Ok(undefined)` if empty, `Err(value)` if already initialized.
|
|
2459
|
+
*
|
|
2460
|
+
* @example
|
|
2461
|
+
* ```ts
|
|
2462
|
+
* const once = Once<number>();
|
|
2463
|
+
*
|
|
2464
|
+
* console.log(once.set(42)); // Ok(undefined)
|
|
2465
|
+
* console.log(once.set(100)); // Err(100) - value returned back
|
|
2466
|
+
* console.log(once.get()); // Some(42)
|
|
2467
|
+
* ```
|
|
2468
|
+
*/
|
|
2469
|
+
set(value: T): Result<void, T>;
|
|
2470
|
+
/**
|
|
2471
|
+
* Gets the contents, initializing it with `fn` if empty.
|
|
2472
|
+
*
|
|
2473
|
+
* @param fn - The synchronous initialization function, called only if empty.
|
|
2474
|
+
* @returns The stored value.
|
|
2475
|
+
*
|
|
2476
|
+
* @example
|
|
2477
|
+
* ```ts
|
|
2478
|
+
* const once = Once<number>();
|
|
2479
|
+
*
|
|
2480
|
+
* const value = once.getOrInit(() => {
|
|
2481
|
+
* console.log('Initializing...');
|
|
2482
|
+
* return 42;
|
|
2483
|
+
* });
|
|
2484
|
+
* console.log(value); // 42
|
|
2485
|
+
*
|
|
2486
|
+
* // Second call - fn is not called
|
|
2487
|
+
* const value2 = once.getOrInit(() => 100);
|
|
2488
|
+
* console.log(value2); // 42
|
|
2489
|
+
* ```
|
|
2490
|
+
*/
|
|
2491
|
+
getOrInit(fn: () => T): T;
|
|
2492
|
+
/**
|
|
2493
|
+
* Gets the contents, initializing it with async `fn` if empty.
|
|
2494
|
+
*
|
|
2495
|
+
* If multiple calls occur concurrently, only the first one will run the
|
|
2496
|
+
* initialization function. Other calls will wait for it to complete.
|
|
2497
|
+
*
|
|
2498
|
+
* @param fn - The async initialization function.
|
|
2499
|
+
* @returns A promise that resolves to the stored value.
|
|
2500
|
+
*
|
|
2501
|
+
* @example
|
|
2502
|
+
* ```ts
|
|
2503
|
+
* const db = Once<Database>();
|
|
2504
|
+
*
|
|
2505
|
+
* // Multiple concurrent calls - only one connection happens
|
|
2506
|
+
* const [db1, db2, db3] = await Promise.all([
|
|
2507
|
+
* db.getOrInitAsync(() => Database.connect(url)),
|
|
2508
|
+
* db.getOrInitAsync(() => Database.connect(url)),
|
|
2509
|
+
* db.getOrInitAsync(() => Database.connect(url)),
|
|
2510
|
+
* ]);
|
|
2511
|
+
* // db1 === db2 === db3
|
|
2512
|
+
* ```
|
|
2513
|
+
*/
|
|
2514
|
+
getOrInitAsync(fn: () => Promise<T>): Promise<T>;
|
|
2515
|
+
/**
|
|
2516
|
+
* Gets the contents, initializing it with `fn` if empty.
|
|
2517
|
+
* If `fn` returns `Err`, remains uninitialized.
|
|
2518
|
+
*
|
|
2519
|
+
* @typeParam E - The error type.
|
|
2520
|
+
* @param fn - The initialization function that may fail.
|
|
2521
|
+
* @returns `Ok(value)` if initialized, `Err(error)` if initialization failed.
|
|
2522
|
+
*
|
|
2523
|
+
* @example
|
|
2524
|
+
* ```ts
|
|
2525
|
+
* const once = Once<Config>();
|
|
2526
|
+
*
|
|
2527
|
+
* const result = once.getOrTryInit(() => {
|
|
2528
|
+
* const config = parseConfig(rawData);
|
|
2529
|
+
* return config ? Ok(config) : Err(new Error('Invalid config'));
|
|
2530
|
+
* });
|
|
2531
|
+
*
|
|
2532
|
+
* if (result.isOk()) {
|
|
2533
|
+
* console.log('Config loaded:', result.unwrap());
|
|
2534
|
+
* }
|
|
2535
|
+
* ```
|
|
2536
|
+
*/
|
|
2537
|
+
getOrTryInit<E>(fn: () => Result<T, E>): Result<T, E>;
|
|
2538
|
+
/**
|
|
2539
|
+
* Gets the contents, initializing it with async `fn` if empty.
|
|
2540
|
+
* If `fn` returns `Err`, remains uninitialized.
|
|
2541
|
+
*
|
|
2542
|
+
* If multiple calls occur concurrently, only the first one will run the
|
|
2543
|
+
* initialization function. Other calls will wait for it to complete.
|
|
2544
|
+
*
|
|
2545
|
+
* @typeParam E - The error type.
|
|
2546
|
+
* @param fn - The async initialization function that may fail.
|
|
2547
|
+
* @returns A promise that resolves to `Ok(value)` or `Err(error)`.
|
|
2548
|
+
*
|
|
2549
|
+
* @example
|
|
2550
|
+
* ```ts
|
|
2551
|
+
* const config = Once<Config>();
|
|
2552
|
+
*
|
|
2553
|
+
* const result = await config.getOrTryInitAsync(async () => {
|
|
2554
|
+
* try {
|
|
2555
|
+
* const response = await fetch('/api/config');
|
|
2556
|
+
* return Ok(await response.json());
|
|
2557
|
+
* } catch (e) {
|
|
2558
|
+
* return Err(e as Error);
|
|
2559
|
+
* }
|
|
2560
|
+
* });
|
|
2561
|
+
* ```
|
|
2562
|
+
*/
|
|
2563
|
+
getOrTryInitAsync<E>(fn: () => Promise<Result<T, E>>): Promise<Result<T, E>>;
|
|
2564
|
+
/**
|
|
2565
|
+
* Takes the value out, leaving it uninitialized.
|
|
2566
|
+
*
|
|
2567
|
+
* @returns `Some(value)` if initialized, `None` otherwise.
|
|
2568
|
+
*
|
|
2569
|
+
* @example
|
|
2570
|
+
* ```ts
|
|
2571
|
+
* const once = Once<number>();
|
|
2572
|
+
* once.set(42);
|
|
2573
|
+
*
|
|
2574
|
+
* console.log(once.take()); // Some(42)
|
|
2575
|
+
* console.log(once.get()); // None - now empty
|
|
2576
|
+
* console.log(once.take()); // None
|
|
2577
|
+
* ```
|
|
2578
|
+
*/
|
|
2579
|
+
take(): Option<T>;
|
|
2580
|
+
/**
|
|
2581
|
+
* Returns `true` if initialized.
|
|
2582
|
+
*
|
|
2583
|
+
* @example
|
|
2584
|
+
* ```ts
|
|
2585
|
+
* const once = Once<number>();
|
|
2586
|
+
* console.log(once.isInitialized()); // false
|
|
2587
|
+
*
|
|
2588
|
+
* once.set(42);
|
|
2589
|
+
* console.log(once.isInitialized()); // true
|
|
2590
|
+
* ```
|
|
2591
|
+
*/
|
|
2592
|
+
isInitialized(): boolean;
|
|
2593
|
+
/**
|
|
2594
|
+
* Custom `toString` implementation.
|
|
2595
|
+
* @example
|
|
2596
|
+
* ```ts
|
|
2597
|
+
* const once = Once<number>();
|
|
2598
|
+
* console.log(once.toString()); // 'Once(<uninitialized>)'
|
|
2599
|
+
*
|
|
2600
|
+
* once.set(42);
|
|
2601
|
+
* console.log(once.toString()); // 'Once(42)'
|
|
2602
|
+
* ```
|
|
2603
|
+
*/
|
|
2604
|
+
toString(): string;
|
|
2605
|
+
}
|
|
2606
|
+
/**
|
|
2607
|
+
* Creates a new empty `Once<T>`.
|
|
2608
|
+
*
|
|
2609
|
+
* @typeParam T - The type of value to store.
|
|
2610
|
+
* @returns A new uninitialized `Once`.
|
|
2611
|
+
*
|
|
2612
|
+
* @example
|
|
2613
|
+
* ```ts
|
|
2614
|
+
* // Basic usage
|
|
2615
|
+
* const once = Once<string>();
|
|
2616
|
+
* once.set('hello');
|
|
2617
|
+
* console.log(once.get().unwrap()); // 'hello'
|
|
2618
|
+
* ```
|
|
2619
|
+
*
|
|
2620
|
+
* @example
|
|
2621
|
+
* ```ts
|
|
2622
|
+
* // Sync lazy singleton pattern
|
|
2623
|
+
* const logger = Once<Logger>();
|
|
2624
|
+
*
|
|
2625
|
+
* function getLogger(): Logger {
|
|
2626
|
+
* return logger.getOrInit(() => new Logger('app'));
|
|
2627
|
+
* }
|
|
2628
|
+
* ```
|
|
2629
|
+
*
|
|
2630
|
+
* @example
|
|
2631
|
+
* ```ts
|
|
2632
|
+
* // Async lazy initialization
|
|
2633
|
+
* const db = Once<Database>();
|
|
2634
|
+
*
|
|
2635
|
+
* async function getDb(): Promise<Database> {
|
|
2636
|
+
* return await db.getOrInitAsync(async () => {
|
|
2637
|
+
* console.log('Connecting to database...');
|
|
2638
|
+
* return await Database.connect(connectionString);
|
|
2639
|
+
* });
|
|
2640
|
+
* }
|
|
2641
|
+
*
|
|
2642
|
+
* // Multiple calls - connection happens only once
|
|
2643
|
+
* const [db1, db2] = await Promise.all([getDb(), getDb()]);
|
|
2644
|
+
* console.log(db1 === db2); // true
|
|
2645
|
+
* ```
|
|
2646
|
+
*
|
|
2647
|
+
* @example
|
|
2648
|
+
* ```ts
|
|
2649
|
+
* // Fallible async initialization
|
|
2650
|
+
* const config = Once<Config>();
|
|
2651
|
+
*
|
|
2652
|
+
* async function loadConfig(): Promise<Result<Config, Error>> {
|
|
2653
|
+
* return await config.getOrTryInitAsync(async () => {
|
|
2654
|
+
* try {
|
|
2655
|
+
* const response = await fetch('/api/config');
|
|
2656
|
+
* if (!response.ok) {
|
|
2657
|
+
* return Err(new Error(`HTTP ${response.status}`));
|
|
2658
|
+
* }
|
|
2659
|
+
* return Ok(await response.json());
|
|
2660
|
+
* } catch (e) {
|
|
2661
|
+
* return Err(e as Error);
|
|
2662
|
+
* }
|
|
2663
|
+
* });
|
|
2664
|
+
* }
|
|
2665
|
+
* ```
|
|
2666
|
+
*/
|
|
2667
|
+
declare function Once<T>(): Once<T>;
|
|
2668
|
+
|
|
2669
|
+
export { Break, Continue, Err, Lazy, LazyAsync, Mutex, None, Ok, Once, RESULT_FALSE, RESULT_TRUE, RESULT_VOID, RESULT_ZERO, Some, isControlFlow, isOption, isResult, promiseToAsyncResult };
|
|
2670
|
+
export type { AsyncIOResult, AsyncOption, AsyncResult, AsyncVoidIOResult, AsyncVoidResult, ControlFlow, IOResult, MutexGuard, Option, Result, VoidIOResult, VoidResult };
|