unthrown 3.0.1 → 4.0.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/README.md +5 -2
- package/dist/index.cjs +215 -43
- package/dist/index.d.cts +556 -120
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +556 -120
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +215 -43
- package/dist/index.mjs.map +1 -1
- package/package.json +4 -5
- package/docs/index.md +0 -1407
package/dist/index.d.cts
CHANGED
|
@@ -16,13 +16,37 @@ type Prettify<T> = { [K in keyof T]: T[K] } & {};
|
|
|
16
16
|
*/
|
|
17
17
|
type Bound<T, K extends string, U> = Prettify<Omit<T, K> & { readonly [P in K]: U }>;
|
|
18
18
|
/**
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
19
|
+
* Compile-time rejection of a thenable callback result — the type-level
|
|
20
|
+
* enforcement of "combinator callbacks are synchronous" (see the
|
|
21
|
+
* {@link AsyncResult} remarks).
|
|
22
|
+
*
|
|
23
|
+
* @remarks
|
|
24
|
+
* Resolves to `unknown` (a no-op in an intersection) for any non-thenable `R`,
|
|
25
|
+
* and to an explanatory string-literal type when `R` is a `PromiseLike` — so an
|
|
26
|
+
* `async` callback fails to compile with the explanation in the error. Without
|
|
27
|
+
* this, `async () => …` would be assignable to `() => void`, and its rejection
|
|
28
|
+
* would escape the pipeline as an unhandled rejection instead of a `Defect`.
|
|
29
|
+
* Lift async work with {@link fromPromise} and compose it with `flatMap`.
|
|
30
|
+
*
|
|
31
|
+
* @typeParam R - the callback's inferred return type.
|
|
32
|
+
* @category Types
|
|
33
|
+
*/
|
|
34
|
+
type NotThenable<R> = [R] extends [PromiseLike<unknown>] ? "unthrown: combinator callbacks are synchronous — lift async work with fromPromise and compose with flatMap" : unknown;
|
|
35
|
+
/**
|
|
36
|
+
* The fluent method surface every {@link Result} variant carries — the
|
|
37
|
+
* combinators (`map`, `flatMap`, `mapErr`, `match`, `unwrap`, …), documented one
|
|
38
|
+
* per entry below. Factored out so the three variants ({@link OkView},
|
|
39
|
+
* {@link ErrView}, {@link DefectView}) can each intersect it; {@link AsyncResult}
|
|
40
|
+
* mirrors this surface with async signatures.
|
|
41
|
+
*
|
|
42
|
+
* @remarks
|
|
43
|
+
* This type exists to **document** the surface and to power narrowing — not to be
|
|
44
|
+
* authored against. You obtain it by holding a `Result` (or `AsyncResult`), never
|
|
45
|
+
* by implementing your own `Result`-like; treat it as read-only reference.
|
|
22
46
|
*
|
|
23
47
|
* @typeParam T - the success value type.
|
|
24
48
|
* @typeParam E - the modeled error type.
|
|
25
|
-
* @
|
|
49
|
+
* @category Methods
|
|
26
50
|
*/
|
|
27
51
|
type ResultMethods<T, E> = {
|
|
28
52
|
/**
|
|
@@ -31,10 +55,12 @@ type ResultMethods<T, E> = {
|
|
|
31
55
|
* Runs `f` only on `Ok`; `Err` and `Defect` pass through untouched. If `f`
|
|
32
56
|
* throws, the thrown value is captured as a `Defect`.
|
|
33
57
|
*
|
|
58
|
+
* An async callback is rejected at compile time ({@link NotThenable}).
|
|
59
|
+
*
|
|
34
60
|
* @typeParam U - the mapped success type.
|
|
35
61
|
* @param f - maps the current success value to a new one.
|
|
36
62
|
*/
|
|
37
|
-
map<U>(f: (value: T) => U): Result$1<U, E>;
|
|
63
|
+
map<U>(f: (value: T) => U & NotThenable<U>): Result$1<U, E>;
|
|
38
64
|
/**
|
|
39
65
|
* Sequence a dependent, `Result`-returning step (monadic bind).
|
|
40
66
|
*
|
|
@@ -50,11 +76,12 @@ type ResultMethods<T, E> = {
|
|
|
50
76
|
* Run a side effect on the success value and pass the `Result` through
|
|
51
77
|
* unchanged.
|
|
52
78
|
*
|
|
53
|
-
* Runs only on `Ok`. If `f` throws, the throw becomes a `Defect`.
|
|
79
|
+
* Runs only on `Ok`. If `f` throws, the throw becomes a `Defect`. An async
|
|
80
|
+
* callback is rejected at compile time ({@link NotThenable}).
|
|
54
81
|
*
|
|
55
82
|
* @param f - the side effect (its return value is ignored).
|
|
56
83
|
*/
|
|
57
|
-
tap(f: (value: T) =>
|
|
84
|
+
tap<R>(f: (value: T) => R & NotThenable<R>): Result$1<T, E>;
|
|
58
85
|
/**
|
|
59
86
|
* Run a **failable** side effect on the success value, keeping the original
|
|
60
87
|
* value but threading the effect's error.
|
|
@@ -99,14 +126,15 @@ type ResultMethods<T, E> = {
|
|
|
99
126
|
* @remarks
|
|
100
127
|
* `f` receives the scope and returns a value (not a `Result`); it is added as
|
|
101
128
|
* `{ ...scope, [name]: value }`. Runs only on `Ok`; `Err`/`Defect` pass
|
|
102
|
-
* through. A throw becomes a `Defect`.
|
|
129
|
+
* through. A throw becomes a `Defect`. An async callback is rejected at
|
|
130
|
+
* compile time ({@link NotThenable}).
|
|
103
131
|
*
|
|
104
132
|
* @typeParam K - the key the value is stored under.
|
|
105
133
|
* @typeParam U - the value type.
|
|
106
134
|
* @param name - the scope key.
|
|
107
135
|
* @param f - computes a value from the accumulated scope.
|
|
108
136
|
*/
|
|
109
|
-
let<K extends string, U>(name: K, f: (scope: T) => U): Result$1<Bound<T, K, U>, E>;
|
|
137
|
+
let<K extends string, U>(name: K, f: (scope: T) => U & NotThenable<U>): Result$1<Bound<T, K, U>, E>;
|
|
110
138
|
/**
|
|
111
139
|
* Replace the success value with a constant `value`.
|
|
112
140
|
*
|
|
@@ -119,12 +147,13 @@ type ResultMethods<T, E> = {
|
|
|
119
147
|
* Transform the modeled error with `f`.
|
|
120
148
|
*
|
|
121
149
|
* Runs `f` only on `Err`; `Ok` passes through and a `Defect` is **never**
|
|
122
|
-
* touched. If `f` throws, the throw becomes a `Defect`.
|
|
150
|
+
* touched. If `f` throws, the throw becomes a `Defect`. An async callback is
|
|
151
|
+
* rejected at compile time ({@link NotThenable}).
|
|
123
152
|
*
|
|
124
153
|
* @typeParam E2 - the mapped error type.
|
|
125
154
|
* @param f - maps the current error to a new one.
|
|
126
155
|
*/
|
|
127
|
-
mapErr<E2>(f: (error: E) => E2): Result$1<T, E2>;
|
|
156
|
+
mapErr<E2>(f: (error: E) => E2 & NotThenable<E2>): Result$1<T, E2>;
|
|
128
157
|
/**
|
|
129
158
|
* Recover from an `Err` by producing another `Result`.
|
|
130
159
|
*
|
|
@@ -144,20 +173,24 @@ type ResultMethods<T, E> = {
|
|
|
144
173
|
* The result type is `Result<T | U, never>`, but `never` describes only the
|
|
145
174
|
* **error** channel — a `Defect` can still be present at runtime, so do not
|
|
146
175
|
* read `never` as "total". Runs `f` only on `Err`; `Ok` and `Defect` pass
|
|
147
|
-
* through. If `f` throws, the throw becomes a `Defect`.
|
|
176
|
+
* through. If `f` throws, the throw becomes a `Defect`. An async callback is
|
|
177
|
+
* rejected at compile time ({@link NotThenable}).
|
|
148
178
|
*
|
|
149
179
|
* @typeParam U - the recovered success type.
|
|
150
180
|
* @param f - produces a success value from the current error.
|
|
151
181
|
*/
|
|
152
|
-
recover<U>(f: (error: E) => U): Result$1<T | U, never>;
|
|
182
|
+
recover<U>(f: (error: E) => U & NotThenable<U>): Result$1<T | U, never>;
|
|
153
183
|
/**
|
|
154
184
|
* Run a side effect on the error and pass the `Result` through unchanged.
|
|
155
185
|
*
|
|
156
|
-
* Runs only on `Err`. If `f` throws, the
|
|
186
|
+
* Runs only on `Err`. If `f` throws, the result is a `Defect` whose cause is
|
|
187
|
+
* an `AggregateError` of `[thrown, original failure]` — observing a failure
|
|
188
|
+
* never destroys it. An async callback is rejected at compile time
|
|
189
|
+
* ({@link NotThenable}).
|
|
157
190
|
*
|
|
158
191
|
* @param f - the side effect (its return value is ignored).
|
|
159
192
|
*/
|
|
160
|
-
tapErr(f: (error: E) =>
|
|
193
|
+
tapErr<R>(f: (error: E) => R & NotThenable<R>): Result$1<T, E>;
|
|
161
194
|
/**
|
|
162
195
|
* Run a **failable** side effect on the error, keeping the original error but
|
|
163
196
|
* threading the effect's own error.
|
|
@@ -167,9 +200,10 @@ type ResultMethods<T, E> = {
|
|
|
167
200
|
* returns a `Result`, but its **success value is discarded** — on the effect's
|
|
168
201
|
* `Ok` the original `Err` flows through unchanged, while an `Err` (or `Defect`)
|
|
169
202
|
* from `f` short-circuits and threads its error (`Result<T, E | E2>`). Runs only
|
|
170
|
-
* on `Err`; `Ok` and `Defect` pass through. If `f` throws, the
|
|
171
|
-
* `Defect
|
|
172
|
-
*
|
|
203
|
+
* on `Err`; `Ok` and `Defect` pass through. If `f` throws, the result is a
|
|
204
|
+
* `Defect` whose cause is an `AggregateError` of `[thrown, original failure]` —
|
|
205
|
+
* observing a failure never destroys it. Use it for a failable effect _during_
|
|
206
|
+
* error handling (e.g. writing the error to an audit log that may itself fail).
|
|
173
207
|
*
|
|
174
208
|
* @typeParam E2 - the error type the effect may introduce.
|
|
175
209
|
* @param f - the failable side effect; its `Ok` value is ignored.
|
|
@@ -191,11 +225,14 @@ type ResultMethods<T, E> = {
|
|
|
191
225
|
recoverDefect<U, E2>(f: (cause: unknown) => Result$1<U, E2>): Result$1<T | U, E | E2>;
|
|
192
226
|
/**
|
|
193
227
|
* Run a side effect on a present `Defect`'s cause (e.g. logging) and pass the
|
|
194
|
-
* `Defect` through unchanged. If `f` throws, the
|
|
228
|
+
* `Defect` through unchanged. If `f` throws, the result is a `Defect` whose
|
|
229
|
+
* cause is an `AggregateError` of `[thrown, original failure]` — observing a
|
|
230
|
+
* failure never destroys it. An async callback is rejected at compile time
|
|
231
|
+
* ({@link NotThenable}).
|
|
195
232
|
*
|
|
196
233
|
* @param f - the side effect over the unknown cause.
|
|
197
234
|
*/
|
|
198
|
-
tapDefect(f: (cause: unknown) =>
|
|
235
|
+
tapDefect<R>(f: (cause: unknown) => R & NotThenable<R>): Result$1<T, E>;
|
|
199
236
|
/**
|
|
200
237
|
* Exhaustively fold all three runtime states into a single value of type `R`.
|
|
201
238
|
*
|
|
@@ -217,35 +254,51 @@ type ResultMethods<T, E> = {
|
|
|
217
254
|
/**
|
|
218
255
|
* Extract the success value.
|
|
219
256
|
*
|
|
257
|
+
* @remarks
|
|
258
|
+
* Compiles only when the error channel is empty (`E = never`) — eliminate
|
|
259
|
+
* modeled errors first (`match` / `recover` / `orElse`), or reach for the
|
|
260
|
+
* `unwrapOr` / `unwrapOrElse` / `getOrNull` / `getOrUndefined` family (which
|
|
261
|
+
* recover an `Err`). If you get a `'this' context` type error here, that is
|
|
262
|
+
* the gate: the receiver still has a non-`never` error channel.
|
|
263
|
+
*
|
|
264
|
+
* `E = never` empties only the **modeled** error channel — a `Defect` can
|
|
265
|
+
* still be present, and `unwrap()` **rethrows its original cause** (it
|
|
266
|
+
* _panics_); `Result<T, never>` does not mean `unwrap()` cannot throw.
|
|
267
|
+
*
|
|
220
268
|
* @returns the `Ok` value.
|
|
221
|
-
* @throws On `Err`, an {@link UnwrapError} carrying the error. On a `Defect`,
|
|
222
|
-
* re-throws the **original cause** with its original stack, so an unhandled
|
|
223
|
-
* Defect surfaces at the global handler as the real failure.
|
|
224
269
|
*/
|
|
225
|
-
unwrap(): T;
|
|
270
|
+
unwrap(this: Result$1<T, never>): T;
|
|
226
271
|
/**
|
|
227
272
|
* Extract the modeled error.
|
|
228
273
|
*
|
|
274
|
+
* @remarks
|
|
275
|
+
* Compiles only when the success channel is empty (`T = never`) — eliminate
|
|
276
|
+
* the success case first. `T = never` is rarely the case in practice (a
|
|
277
|
+
* `Result` you hold usually still has a success type), so to inspect an
|
|
278
|
+
* error prefer an `isErr()` guard or, in tests, `@unthrown/vitest`'s
|
|
279
|
+
* `toBeErrWith`. A `Defect` still **rethrows its original cause** (a defect is
|
|
280
|
+
* a bug, not an absent value), so this does not mean `unwrapErr()` can't throw.
|
|
281
|
+
*
|
|
229
282
|
* @returns the `Err` value.
|
|
230
|
-
* @throws On `Ok`, an {@link UnwrapError} carrying the value. On a `Defect`,
|
|
231
|
-
* re-throws the original cause.
|
|
232
283
|
*/
|
|
233
|
-
unwrapErr(): E;
|
|
284
|
+
unwrapErr(this: Result$1<never, E>): E;
|
|
234
285
|
/**
|
|
235
286
|
* The success value, or `fallback` on `Err`.
|
|
236
287
|
*
|
|
237
|
-
* @
|
|
288
|
+
* @typeParam U - the fallback type (may differ from `T`; the return widens to `T | U`).
|
|
289
|
+
* @param fallback - returned when the result is an `Err` (may be a different type; the return widens to `T | U`).
|
|
238
290
|
* @throws Re-throws on a `Defect` — a Defect is a bug, not an absent value, so
|
|
239
291
|
* it is never silently replaced.
|
|
240
292
|
*/
|
|
241
|
-
unwrapOr(fallback:
|
|
293
|
+
unwrapOr<U>(fallback: U): T | U;
|
|
242
294
|
/**
|
|
243
295
|
* The success value, or `f(error)` on `Err`.
|
|
244
296
|
*
|
|
245
|
-
* @
|
|
297
|
+
* @typeParam U - the fallback type (may differ from `T`; the return widens to `T | U`).
|
|
298
|
+
* @param f - lazily computes the fallback from the error (may return a different type; the return widens to `T | U`).
|
|
246
299
|
* @throws Re-throws on a `Defect`.
|
|
247
300
|
*/
|
|
248
|
-
unwrapOrElse(f: (error: E) =>
|
|
301
|
+
unwrapOrElse<U>(f: (error: E) => U): T | U;
|
|
249
302
|
/**
|
|
250
303
|
* The success value, or `null` on `Err`.
|
|
251
304
|
*
|
|
@@ -263,17 +316,58 @@ type ResultMethods<T, E> = {
|
|
|
263
316
|
isDefect(): this is DefectView<T, E>; /** Lift this synchronous `Result` into an {@link AsyncResult}. */
|
|
264
317
|
toAsync(): AsyncResult$1<T, E>;
|
|
265
318
|
};
|
|
266
|
-
/**
|
|
319
|
+
/**
|
|
320
|
+
* The `Ok` variant of a {@link Result}: a success carrying a `value`. This is
|
|
321
|
+
* what a successful `isOk` guard narrows to, making `.value` reachable. It also
|
|
322
|
+
* carries the shared fluent surface ({@link ResultMethods}).
|
|
323
|
+
*
|
|
324
|
+
* @example
|
|
325
|
+
* ```ts
|
|
326
|
+
* if (r.isOk()) r.value; // r: OkView<T, E> here — .value is a T
|
|
327
|
+
* ```
|
|
328
|
+
*
|
|
329
|
+
* @category Types
|
|
330
|
+
*/
|
|
267
331
|
type OkView<T, E = never> = ResultMethods<T, E> & {
|
|
268
332
|
readonly tag: "Ok";
|
|
269
333
|
readonly value: T;
|
|
270
334
|
};
|
|
271
|
-
/**
|
|
335
|
+
/**
|
|
336
|
+
* The `Err` variant of a {@link Result}: a modeled failure carrying an `error`.
|
|
337
|
+
* This is what a successful `isErr` guard narrows to, exposing `.error`. It also
|
|
338
|
+
* carries the shared fluent surface ({@link ResultMethods}).
|
|
339
|
+
*
|
|
340
|
+
* @remarks
|
|
341
|
+
* **Note the parameter order: `ErrView<E, T>` puts the error type _first_** — the
|
|
342
|
+
* reverse of the `<T, E>` order used by {@link OkView}, {@link DefectView}, and
|
|
343
|
+
* {@link Result} — because `Result<T, E>` narrows to `ErrView<E, T>` (the error is
|
|
344
|
+
* the payload the guard makes reachable). You rarely write it by hand (a failed
|
|
345
|
+
* `isErr()` narrows to it for you); if you do, mind the flip — `ErrView<MyError,
|
|
346
|
+
* MyValue>`, not `ErrView<MyValue, MyError>`.
|
|
347
|
+
*
|
|
348
|
+
* @example
|
|
349
|
+
* ```ts
|
|
350
|
+
* if (r.isErr()) r.error; // r: ErrView<E, T> here — .error is an E
|
|
351
|
+
* ```
|
|
352
|
+
*
|
|
353
|
+
* @category Types
|
|
354
|
+
*/
|
|
272
355
|
type ErrView<E, T = never> = ResultMethods<T, E> & {
|
|
273
356
|
readonly tag: "Err";
|
|
274
357
|
readonly error: E;
|
|
275
358
|
};
|
|
276
|
-
/**
|
|
359
|
+
/**
|
|
360
|
+
* The `Defect` variant of a {@link Result}: an unmodeled failure carrying a
|
|
361
|
+
* `cause`. This is what a successful `isDefect` guard narrows to, exposing
|
|
362
|
+
* `.cause`. It also carries the shared fluent surface ({@link ResultMethods}).
|
|
363
|
+
*
|
|
364
|
+
* @example
|
|
365
|
+
* ```ts
|
|
366
|
+
* if (r.isDefect()) r.cause; // r: DefectView<T, E> here — .cause is `unknown`
|
|
367
|
+
* ```
|
|
368
|
+
*
|
|
369
|
+
* @category Types
|
|
370
|
+
*/
|
|
277
371
|
type DefectView<T = never, E = never> = ResultMethods<T, E> & {
|
|
278
372
|
readonly tag: "Defect";
|
|
279
373
|
readonly cause: unknown;
|
|
@@ -324,107 +418,233 @@ type Result$1<T, E> = OkView<T, E> | ErrView<E, T> | DefectView<T, E>;
|
|
|
324
418
|
* An {@link AsyncResult}'s internal promise never rejects, so `await`-ing one
|
|
325
419
|
* always yields a {@link Result} and never throws — there is no rejection
|
|
326
420
|
* channel to model, and none is advertised. At runtime it is still a thenable
|
|
327
|
-
* (the only way `await` can collapse it)
|
|
328
|
-
*
|
|
421
|
+
* (the only way `await` can collapse it), and `Promise.all` / `Promise.resolve`
|
|
422
|
+
* will still adopt it — harmlessly, since it settles to a `Result` and never
|
|
423
|
+
* rejects. What the narrowing prevents is treating it as a full promise:
|
|
424
|
+
* `.catch()` / `.finally()` do not type-check, because there is no rejection to
|
|
425
|
+
* handle.
|
|
329
426
|
*
|
|
330
427
|
* @typeParam T - the value `await` resolves to.
|
|
428
|
+
*
|
|
429
|
+
* @category Types
|
|
331
430
|
*/
|
|
332
431
|
type Awaitable<T> = {
|
|
333
432
|
then<R = T>(onfulfilled?: ((value: T) => R | PromiseLike<R>) | null): PromiseLike<R>;
|
|
334
433
|
};
|
|
335
434
|
/**
|
|
336
|
-
* The
|
|
337
|
-
*
|
|
435
|
+
* The async method surface every {@link AsyncResult} carries — the combinators
|
|
436
|
+
* (`map`, `flatMap`, `mapErr`, `match`, `unwrap`, …) with their asynchronous
|
|
437
|
+
* signatures, documented one per entry below. The async mirror of
|
|
438
|
+
* {@link ResultMethods}: each entry links its synchronous counterpart and states
|
|
439
|
+
* only the async delta.
|
|
338
440
|
*
|
|
339
441
|
* @remarks
|
|
340
|
-
*
|
|
341
|
-
*
|
|
342
|
-
*
|
|
343
|
-
* {@link
|
|
344
|
-
*
|
|
345
|
-
*
|
|
346
|
-
*
|
|
347
|
-
* `AsyncResult`.
|
|
348
|
-
*
|
|
349
|
-
* To pattern-match an `AsyncResult`, `await` it first: `match(await ar)`.
|
|
442
|
+
* Like {@link ResultMethods}, this type exists to **document** the surface — not
|
|
443
|
+
* to be authored against; you obtain it by holding an `AsyncResult`. Its
|
|
444
|
+
* combinator callbacks are **synchronous** (a raw `Promise` may never enter — see
|
|
445
|
+
* the {@link AsyncResult} remarks); async work re-enters via {@link fromPromise}
|
|
446
|
+
* and composes with `flatMap`. Systematic differences from the sync surface: the
|
|
447
|
+
* binds return an `AsyncResult` (and additionally accept one), and the
|
|
448
|
+
* eliminators return a `Promise`.
|
|
350
449
|
*
|
|
351
450
|
* @typeParam T - the success value type.
|
|
352
451
|
* @typeParam E - the modeled error type.
|
|
452
|
+
* @category Methods
|
|
353
453
|
*/
|
|
354
|
-
type
|
|
355
|
-
/** Asynchronous `map`. `f` is synchronous; a throw becomes a `Defect`. */map<U>(f: (value: T) => U): AsyncResult$1<U, E>;
|
|
454
|
+
type AsyncResultMethods<T, E> = {
|
|
356
455
|
/**
|
|
357
|
-
* Asynchronous
|
|
358
|
-
*
|
|
456
|
+
* Asynchronous {@link ResultMethods.map | map}: transforms the success value
|
|
457
|
+
* with `f`. `f` is synchronous; a throw becomes a `Defect`. An async callback
|
|
458
|
+
* is rejected at compile time ({@link NotThenable}).
|
|
359
459
|
*/
|
|
360
|
-
|
|
361
|
-
tap(f: (value: T) => void): AsyncResult$1<T, E>;
|
|
460
|
+
map<U>(f: (value: T) => U & NotThenable<U>): AsyncResult$1<U, E>;
|
|
362
461
|
/**
|
|
363
|
-
* Asynchronous
|
|
364
|
-
* may return a `Result` **or** an `AsyncResult
|
|
365
|
-
*
|
|
462
|
+
* Asynchronous {@link ResultMethods.flatMap | flatMap}. Unlike the sync form,
|
|
463
|
+
* `f` may return a `Result` **or** an `AsyncResult` (never a raw `Promise`); a
|
|
464
|
+
* throw becomes a `Defect`.
|
|
366
465
|
*/
|
|
367
|
-
|
|
466
|
+
flatMap<U, E2>(f: (value: T) => Result$1<U, E2> | AsyncResult$1<U, E2>): AsyncResult$1<U, E | E2>;
|
|
368
467
|
/**
|
|
369
|
-
* Asynchronous
|
|
370
|
-
*
|
|
468
|
+
* Asynchronous {@link ResultMethods.tap | tap}. `f` is synchronous; a throw
|
|
469
|
+
* becomes a `Defect`. An async callback is rejected at compile time
|
|
470
|
+
* ({@link NotThenable}).
|
|
371
471
|
*/
|
|
372
|
-
|
|
373
|
-
let<K extends string, U>(name: K, f: (scope: T) => U): AsyncResult$1<Bound<T, K, U>, E>; /** Asynchronous `as`. */
|
|
374
|
-
as<U>(value: U): AsyncResult$1<U, E>; /** Asynchronous `mapErr`. `f` is synchronous; a throw becomes a `Defect`. */
|
|
375
|
-
mapErr<E2>(f: (error: E) => E2): AsyncResult$1<T, E2>; /** Asynchronous `orElse`. `f` may return a `Result` or an `AsyncResult`. */
|
|
376
|
-
orElse<U, E2>(f: (error: E) => Result$1<U, E2> | AsyncResult$1<U, E2>): AsyncResult$1<T | U, E2>; /** Asynchronous `recover`. `f` is synchronous; a throw becomes a `Defect`. */
|
|
377
|
-
recover<U>(f: (error: E) => U): AsyncResult$1<T | U, never>; /** Asynchronous `tapErr`. `f` is synchronous; a throw becomes a `Defect`. */
|
|
378
|
-
tapErr(f: (error: E) => void): AsyncResult$1<T, E>;
|
|
472
|
+
tap<R>(f: (value: T) => R & NotThenable<R>): AsyncResult$1<T, E>;
|
|
379
473
|
/**
|
|
380
|
-
* Asynchronous
|
|
381
|
-
* original
|
|
382
|
-
* value is discarded, an `Err`/`Defect`
|
|
474
|
+
* Asynchronous {@link ResultMethods.flatTap | flatTap} — a failable tap that
|
|
475
|
+
* keeps the original value. `f` may return a `Result` **or** an `AsyncResult`;
|
|
476
|
+
* its `Ok` value is discarded, an `Err`/`Defect` short-circuits, and a throw
|
|
383
477
|
* becomes a `Defect`.
|
|
384
478
|
*/
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
479
|
+
flatTap<E2>(f: (value: T) => Result$1<unknown, E2> | AsyncResult$1<unknown, E2>): AsyncResult$1<T, E | E2>;
|
|
480
|
+
/**
|
|
481
|
+
* Asynchronous {@link ResultMethods.bind | bind} (do-notation). `f` may return
|
|
482
|
+
* a `Result` **or** an `AsyncResult`; its value is bound under `name` in the
|
|
483
|
+
* accumulating scope.
|
|
484
|
+
*/
|
|
485
|
+
bind<K extends string, U, E2>(name: K, f: (scope: T) => Result$1<U, E2> | AsyncResult$1<U, E2>): AsyncResult$1<Bound<T, K, U>, E | E2>;
|
|
486
|
+
/**
|
|
487
|
+
* Asynchronous {@link ResultMethods.let | let} (do-notation). `f` returns a
|
|
488
|
+
* plain value, bound under `name`. An async callback is rejected at compile
|
|
489
|
+
* time ({@link NotThenable}).
|
|
490
|
+
*/
|
|
491
|
+
let<K extends string, U>(name: K, f: (scope: T) => U & NotThenable<U>): AsyncResult$1<Bound<T, K, U>, E>; /** Asynchronous {@link ResultMethods.as | as}: replaces the value with `value`. */
|
|
492
|
+
as<U>(value: U): AsyncResult$1<U, E>;
|
|
493
|
+
/**
|
|
494
|
+
* Asynchronous {@link ResultMethods.mapErr | mapErr}. `f` is synchronous; a
|
|
495
|
+
* throw becomes a `Defect`. An async callback is rejected at compile time
|
|
496
|
+
* ({@link NotThenable}).
|
|
497
|
+
*/
|
|
498
|
+
mapErr<E2>(f: (error: E) => E2 & NotThenable<E2>): AsyncResult$1<T, E2>;
|
|
499
|
+
/**
|
|
500
|
+
* Asynchronous {@link ResultMethods.orElse | orElse}. `f` may return a `Result`
|
|
501
|
+
* or an `AsyncResult`.
|
|
502
|
+
*/
|
|
503
|
+
orElse<U, E2>(f: (error: E) => Result$1<U, E2> | AsyncResult$1<U, E2>): AsyncResult$1<T | U, E2>;
|
|
504
|
+
/**
|
|
505
|
+
* Asynchronous {@link ResultMethods.recover | recover}. `f` is synchronous; a
|
|
506
|
+
* throw becomes a `Defect`. An async callback is rejected at compile time
|
|
507
|
+
* ({@link NotThenable}).
|
|
508
|
+
*/
|
|
509
|
+
recover<U>(f: (error: E) => U & NotThenable<U>): AsyncResult$1<T | U, never>;
|
|
510
|
+
/**
|
|
511
|
+
* Asynchronous {@link ResultMethods.tapErr | tapErr}. `f` is synchronous; if it
|
|
512
|
+
* throws, the result is a `Defect` whose cause is an `AggregateError` of
|
|
513
|
+
* `[thrown, original failure]` — observing a failure never destroys it. An
|
|
514
|
+
* async callback is rejected at compile time ({@link NotThenable}).
|
|
515
|
+
*/
|
|
516
|
+
tapErr<R>(f: (error: E) => R & NotThenable<R>): AsyncResult$1<T, E>;
|
|
517
|
+
/**
|
|
518
|
+
* Asynchronous {@link ResultMethods.flatTapErr | flatTapErr} — the
|
|
519
|
+
* error-channel mirror of `flatTap`. `f` may return a `Result` **or** an
|
|
520
|
+
* `AsyncResult`; its `Ok` value is discarded, an `Err`/`Defect` from `f`
|
|
521
|
+
* threads through, and if `f` throws, the result is a `Defect` whose cause is
|
|
522
|
+
* an `AggregateError` of `[thrown, original failure]` — observing a failure
|
|
523
|
+
* never destroys it.
|
|
524
|
+
*/
|
|
525
|
+
flatTapErr<E2>(f: (error: E) => Result$1<unknown, E2> | AsyncResult$1<unknown, E2>): AsyncResult$1<T, E | E2>;
|
|
526
|
+
/**
|
|
527
|
+
* Asynchronous {@link ResultMethods.recoverDefect | recoverDefect}. `f` may
|
|
528
|
+
* return a `Result` or an `AsyncResult`.
|
|
529
|
+
*/
|
|
530
|
+
recoverDefect<U, E2>(f: (cause: unknown) => Result$1<U, E2> | AsyncResult$1<U, E2>): AsyncResult$1<T | U, E | E2>;
|
|
531
|
+
/**
|
|
532
|
+
* Asynchronous {@link ResultMethods.tapDefect | tapDefect}. If `f` throws, the
|
|
533
|
+
* result is a `Defect` whose cause is an `AggregateError` of `[thrown,
|
|
534
|
+
* original failure]` — observing a failure never destroys it. An async
|
|
535
|
+
* callback is rejected at compile time ({@link NotThenable}).
|
|
536
|
+
*/
|
|
537
|
+
tapDefect<R>(f: (cause: unknown) => R & NotThenable<R>): AsyncResult$1<T, E>;
|
|
538
|
+
/**
|
|
539
|
+
* Asynchronous {@link ResultMethods.match | match}. Handlers are synchronous;
|
|
540
|
+
* resolves to a `Promise<R>`.
|
|
541
|
+
*/
|
|
388
542
|
match<R>(cases: {
|
|
389
543
|
ok: (value: T) => R;
|
|
390
544
|
err: (error: E) => R;
|
|
391
545
|
defect: (cause: unknown) => R;
|
|
392
|
-
}): Promise<R>;
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
546
|
+
}): Promise<R>;
|
|
547
|
+
/**
|
|
548
|
+
* Asynchronous {@link ResultMethods.unwrap | unwrap}. Compiles only when the
|
|
549
|
+
* error channel is empty (`this: AsyncResult<T, never>`); the returned promise
|
|
550
|
+
* rejects on a `Defect` (rethrowing its cause).
|
|
551
|
+
*/
|
|
552
|
+
unwrap(this: AsyncResult$1<T, never>): Promise<T>;
|
|
553
|
+
/**
|
|
554
|
+
* Asynchronous {@link ResultMethods.unwrapErr | unwrapErr}. Compiles only when
|
|
555
|
+
* the success channel is empty (`this: AsyncResult<never, E>`); the returned
|
|
556
|
+
* promise rejects on a `Defect` (rethrowing its cause).
|
|
557
|
+
*/
|
|
558
|
+
unwrapErr(this: AsyncResult$1<never, E>): Promise<E>; /** Asynchronous {@link ResultMethods.unwrapOr | unwrapOr}. */
|
|
559
|
+
unwrapOr<U>(fallback: U): Promise<T | U>; /** Asynchronous {@link ResultMethods.unwrapOrElse | unwrapOrElse}. */
|
|
560
|
+
unwrapOrElse<U>(f: (error: E) => U): Promise<T | U>; /** Asynchronous {@link ResultMethods.getOrNull | getOrNull}. */
|
|
561
|
+
getOrNull(): Promise<T | null>; /** Asynchronous {@link ResultMethods.getOrUndefined | getOrUndefined}. */
|
|
398
562
|
getOrUndefined(): Promise<T | undefined>;
|
|
399
563
|
};
|
|
400
564
|
/**
|
|
401
|
-
*
|
|
565
|
+
* The asynchronous counterpart of {@link Result}: an awaitable wrapper carrying
|
|
566
|
+
* the {@link AsyncResultMethods} surface, collapsing to a `Result<T, E>` when
|
|
567
|
+
* `await`-ed.
|
|
568
|
+
*
|
|
569
|
+
* @remarks
|
|
570
|
+
* **Combinator callbacks are synchronous.** A raw `Promise` may never enter an
|
|
571
|
+
* `AsyncResult` method — that would be an un-qualified async boundary, and its
|
|
572
|
+
* rejection would silently become a `Defect`, skipping the triage that
|
|
573
|
+
* {@link fromPromise} forces. To do further async work, re-enter through a
|
|
574
|
+
* qualified boundary and compose it: `ar.flatMap((v) => fromPromise(work(v),
|
|
575
|
+
* qualify))`. The eliminators (`unwrap`, …) return promises; the binds
|
|
576
|
+
* (`flatMap`, `flatTap`, `orElse`, `recoverDefect`) additionally accept an
|
|
577
|
+
* `AsyncResult`. Its combinators are documented one per entry on
|
|
578
|
+
* {@link AsyncResultMethods}.
|
|
579
|
+
*
|
|
580
|
+
* To pattern-match an `AsyncResult`, `await` it first: `match(await ar)`.
|
|
581
|
+
*
|
|
582
|
+
* @typeParam T - the success value type.
|
|
583
|
+
* @typeParam E - the modeled error type.
|
|
584
|
+
*/
|
|
585
|
+
type AsyncResult$1<T, E> = Awaitable<Result$1<T, E>> & AsyncResultMethods<T, E>;
|
|
586
|
+
/**
|
|
587
|
+
* Extract the success type `T` from a `Result` type — derive one type from
|
|
588
|
+
* another instead of restating it (e.g. the payload a function returns).
|
|
402
589
|
*
|
|
403
590
|
* @typeParam R - the `Result` type to inspect.
|
|
591
|
+
*
|
|
592
|
+
* @example
|
|
593
|
+
* ```ts
|
|
594
|
+
* type R = Result<User, NotFound>;
|
|
595
|
+
* type U = OkOf<R>; // User
|
|
596
|
+
* type E = ErrOf<R>; // NotFound
|
|
597
|
+
* ```
|
|
598
|
+
*
|
|
599
|
+
* @category Types
|
|
404
600
|
*/
|
|
405
601
|
type OkOf<R> = R extends {
|
|
406
602
|
readonly tag: "Ok";
|
|
407
603
|
readonly value: infer T;
|
|
408
604
|
} ? T : never;
|
|
409
605
|
/**
|
|
410
|
-
* Extract the error type `E` from a `Result
|
|
606
|
+
* Extract the error type `E` from a `Result` type — the counterpart of
|
|
607
|
+
* {@link OkOf}.
|
|
411
608
|
*
|
|
412
609
|
* @typeParam R - the `Result` type to inspect.
|
|
610
|
+
*
|
|
611
|
+
* @example
|
|
612
|
+
* ```ts
|
|
613
|
+
* type E = ErrOf<Result<User, NotFound>>; // NotFound
|
|
614
|
+
* ```
|
|
615
|
+
*
|
|
616
|
+
* @category Types
|
|
413
617
|
*/
|
|
414
618
|
type ErrOf<R> = R extends {
|
|
415
619
|
readonly tag: "Err";
|
|
416
620
|
readonly error: infer E;
|
|
417
621
|
} ? E : never;
|
|
418
622
|
/**
|
|
419
|
-
* Extract the success type `T` from an {@link AsyncResult}
|
|
623
|
+
* Extract the success type `T` from an {@link AsyncResult} type — the async
|
|
624
|
+
* counterpart of {@link OkOf}.
|
|
420
625
|
*
|
|
421
626
|
* @typeParam R - the `AsyncResult` type to inspect.
|
|
627
|
+
*
|
|
628
|
+
* @example
|
|
629
|
+
* ```ts
|
|
630
|
+
* type T = AsyncOkOf<AsyncResult<User, NotFound>>; // User
|
|
631
|
+
* ```
|
|
632
|
+
*
|
|
633
|
+
* @category Types
|
|
422
634
|
*/
|
|
423
635
|
type AsyncOkOf<R> = R extends AsyncResult$1<infer T, unknown> ? T : never;
|
|
424
636
|
/**
|
|
425
|
-
* Extract the error type `E` from an {@link AsyncResult}
|
|
637
|
+
* Extract the error type `E` from an {@link AsyncResult} type — the async
|
|
638
|
+
* counterpart of {@link ErrOf}.
|
|
426
639
|
*
|
|
427
640
|
* @typeParam R - the `AsyncResult` type to inspect.
|
|
641
|
+
*
|
|
642
|
+
* @example
|
|
643
|
+
* ```ts
|
|
644
|
+
* type E = AsyncErrOf<AsyncResult<User, NotFound>>; // NotFound
|
|
645
|
+
* ```
|
|
646
|
+
*
|
|
647
|
+
* @category Types
|
|
428
648
|
*/
|
|
429
649
|
type AsyncErrOf<R> = R extends AsyncResult$1<unknown, infer E> ? E : never;
|
|
430
650
|
//#endregion
|
|
@@ -438,8 +658,12 @@ type AsyncErrOf<R> = R extends AsyncResult$1<unknown, infer E> ? E : never;
|
|
|
438
658
|
* @example
|
|
439
659
|
* ```ts
|
|
440
660
|
* import { Ok } from "unthrown";
|
|
441
|
-
*
|
|
661
|
+
*
|
|
662
|
+
* Ok(2).map((n) => n + 1); // => Ok(3)
|
|
663
|
+
* Ok(42).unwrap(); // => 42
|
|
442
664
|
* ```
|
|
665
|
+
*
|
|
666
|
+
* @category Constructors
|
|
443
667
|
*/
|
|
444
668
|
declare function Ok<T>(value: T): Result$1<T, never>;
|
|
445
669
|
/**
|
|
@@ -451,8 +675,12 @@ declare function Ok<T>(value: T): Result$1<T, never>;
|
|
|
451
675
|
* @example
|
|
452
676
|
* ```ts
|
|
453
677
|
* import { Err } from "unthrown";
|
|
454
|
-
*
|
|
678
|
+
*
|
|
679
|
+
* Err("not_found").map((n) => n + 1); // => Err("not_found") (map skipped)
|
|
680
|
+
* Err("not_found").unwrapErr(); // => "not_found"
|
|
455
681
|
* ```
|
|
682
|
+
*
|
|
683
|
+
* @category Constructors
|
|
456
684
|
*/
|
|
457
685
|
declare function Err<E>(error: E): Result$1<never, E>;
|
|
458
686
|
/**
|
|
@@ -462,22 +690,61 @@ declare function Err<E>(error: E): Result$1<never, E>;
|
|
|
462
690
|
*
|
|
463
691
|
* @example
|
|
464
692
|
* ```ts
|
|
465
|
-
* import { isOk, type Result } from "unthrown";
|
|
693
|
+
* import { isOk, Ok, Err, type Result } from "unthrown";
|
|
694
|
+
*
|
|
695
|
+
* isOk(Ok(1)); // => true
|
|
696
|
+
* isOk(Err("boom")); // => false
|
|
697
|
+
*
|
|
466
698
|
* declare const r: Result<number, string>;
|
|
467
699
|
* if (isOk(r)) r.value; // number, narrowed
|
|
468
700
|
* ```
|
|
701
|
+
*
|
|
702
|
+
* @category Guards
|
|
469
703
|
*/
|
|
470
704
|
declare function isOk<T, E>(r: Result$1<T, E>): r is OkView<T, E>;
|
|
471
705
|
/**
|
|
472
706
|
* Type guard: narrow a {@link Result} to its `Err` variant, exposing `.error`.
|
|
473
707
|
*
|
|
474
708
|
* @returns `true` when `r` is `Err`.
|
|
709
|
+
*
|
|
710
|
+
* @example
|
|
711
|
+
* ```ts
|
|
712
|
+
* import { isErr, Ok, Err, type Result } from "unthrown";
|
|
713
|
+
*
|
|
714
|
+
* isErr(Err("boom")); // => true
|
|
715
|
+
* isErr(Ok(1)); // => false
|
|
716
|
+
*
|
|
717
|
+
* declare const r: Result<number, string>;
|
|
718
|
+
* if (isErr(r)) r.error; // string, narrowed
|
|
719
|
+
* ```
|
|
720
|
+
*
|
|
721
|
+
* @category Guards
|
|
475
722
|
*/
|
|
476
723
|
declare function isErr<T, E>(r: Result$1<T, E>): r is ErrView<E, T>;
|
|
477
724
|
/**
|
|
478
725
|
* Type guard: narrow a {@link Result} to its `Defect` variant, exposing `.cause`.
|
|
479
726
|
*
|
|
727
|
+
* @remarks
|
|
728
|
+
* A `Defect` has no public constructor — it only arises at a boundary (e.g. a
|
|
729
|
+
* callback throwing inside a combinator). This guard is how you detect one.
|
|
730
|
+
*
|
|
480
731
|
* @returns `true` when `r` is a `Defect`.
|
|
732
|
+
*
|
|
733
|
+
* @example
|
|
734
|
+
* ```ts
|
|
735
|
+
* import { isDefect, Ok } from "unthrown";
|
|
736
|
+
*
|
|
737
|
+
* // A throw inside a combinator is captured as a Defect:
|
|
738
|
+
* const r = Ok(1).map(() => {
|
|
739
|
+
* throw new Error("boom");
|
|
740
|
+
* });
|
|
741
|
+
* isDefect(r); // => true
|
|
742
|
+
* isDefect(Ok(1)); // => false
|
|
743
|
+
*
|
|
744
|
+
* if (isDefect(r)) r.cause; // unknown, narrowed
|
|
745
|
+
* ```
|
|
746
|
+
*
|
|
747
|
+
* @category Guards
|
|
481
748
|
*/
|
|
482
749
|
declare function isDefect<T, E>(r: Result$1<T, E>): r is DefectView<T, E>;
|
|
483
750
|
//#endregion
|
|
@@ -496,7 +763,14 @@ declare function isDefect<T, E>(r: Result$1<T, E>): r is DefectView<T, E>;
|
|
|
496
763
|
* A `Defect` is never wrapped in an `UnwrapError`: its original cause is
|
|
497
764
|
* re-thrown (with its original stack) instead.
|
|
498
765
|
*
|
|
766
|
+
* `unwrap()` and `unwrapErr()` are type-gated (`this: Result<T, never>` /
|
|
767
|
+
* `Result<never, E>`), so the wrong-variant branch that throws this is
|
|
768
|
+
* unreachable through well-typed code — it remains only as a defensive guard
|
|
769
|
+
* against unsound runtime misuse (e.g. an `as` cast past the gate).
|
|
770
|
+
*
|
|
499
771
|
* @typeParam E - the type of the {@link UnwrapError.error} it carries.
|
|
772
|
+
*
|
|
773
|
+
* @category Errors
|
|
500
774
|
*/
|
|
501
775
|
declare class UnwrapError<E = unknown> extends Error {
|
|
502
776
|
/**
|
|
@@ -517,6 +791,20 @@ declare class UnwrapError<E = unknown> extends Error {
|
|
|
517
791
|
* is not a `Result` and returns `false`.
|
|
518
792
|
*
|
|
519
793
|
* @returns `true` when `x` is a `Result` produced by this library.
|
|
794
|
+
*
|
|
795
|
+
* @example
|
|
796
|
+
* ```ts
|
|
797
|
+
* import { isResult, Ok } from "unthrown";
|
|
798
|
+
*
|
|
799
|
+
* isResult(Ok(1)); // => true
|
|
800
|
+
* isResult({ tag: "Ok" }); // => false (look-alike, wrong prototype)
|
|
801
|
+
* isResult(Ok(1).toAsync()); // => false (an AsyncResult is not a Result)
|
|
802
|
+
*
|
|
803
|
+
* const x: unknown = Ok(1);
|
|
804
|
+
* if (isResult(x)) x.match({ ok: () => 1, err: () => 0, defect: () => -1 });
|
|
805
|
+
* ```
|
|
806
|
+
*
|
|
807
|
+
* @category Guards
|
|
520
808
|
*/
|
|
521
809
|
declare function isResult(x: unknown): x is Result$1<unknown, unknown>;
|
|
522
810
|
//#endregion
|
|
@@ -542,6 +830,24 @@ declare function isResult(x: unknown): x is Result$1<unknown, unknown>;
|
|
|
542
830
|
* .map(({ user, org, label }) => render(user, org, label));
|
|
543
831
|
* // Result<View, NotFound>
|
|
544
832
|
* ```
|
|
833
|
+
*
|
|
834
|
+
* @example
|
|
835
|
+
* ```ts
|
|
836
|
+
* import { Do, Ok, Err } from "unthrown";
|
|
837
|
+
*
|
|
838
|
+
* // Ok path — the scope accumulates:
|
|
839
|
+
* Do()
|
|
840
|
+
* .bind("a", () => Ok(2))
|
|
841
|
+
* .let("b", ({ a }) => a * 10)
|
|
842
|
+
* .map(({ a, b }) => a + b); // => Ok(22)
|
|
843
|
+
*
|
|
844
|
+
* // Err path — the first Err short-circuits the rest:
|
|
845
|
+
* Do()
|
|
846
|
+
* .bind("a", () => Err("boom"))
|
|
847
|
+
* .let("b", ({ a }) => a); // => Err("boom")
|
|
848
|
+
* ```
|
|
849
|
+
*
|
|
850
|
+
* @category Do-notation
|
|
545
851
|
*/
|
|
546
852
|
declare function Do(): Result$1<{}, never>;
|
|
547
853
|
//#endregion
|
|
@@ -580,10 +886,16 @@ type Defect = {
|
|
|
580
886
|
* @param value - the possibly-absent value.
|
|
581
887
|
* @param onAbsent - lazily produces the error for the absent case.
|
|
582
888
|
*
|
|
889
|
+
* @category Interop
|
|
890
|
+
*
|
|
583
891
|
* @example
|
|
584
892
|
* ```ts
|
|
585
893
|
* import { fromNullable } from "unthrown";
|
|
586
|
-
*
|
|
894
|
+
*
|
|
895
|
+
* const map = new Map([["a", 1]]);
|
|
896
|
+
* fromNullable(map.get("a"), () => "absent").unwrapOr(0); // => 1
|
|
897
|
+
* fromNullable(map.get("z"), () => "absent"); // => Err("absent")
|
|
898
|
+
* fromNullable(0, () => "absent").unwrapOr(-1); // => 0 (falsy but present)
|
|
587
899
|
* ```
|
|
588
900
|
*/
|
|
589
901
|
declare function fromNullable<T, E>(value: T | null | undefined, onAbsent: () => E): Result$1<NonNullable<T>, E>;
|
|
@@ -612,11 +924,21 @@ declare function fromNullable<T, E>(value: T | null | undefined, onAbsent: () =>
|
|
|
612
924
|
* unmodeled by returning `defect(cause)` (the helper passed as its second arg).
|
|
613
925
|
* @returns a function with the same arguments returning `Result<T, E>`.
|
|
614
926
|
*
|
|
927
|
+
* @category Interop
|
|
928
|
+
*
|
|
615
929
|
* @example
|
|
616
930
|
* ```ts
|
|
617
931
|
* import { fromThrowable } from "unthrown";
|
|
618
|
-
*
|
|
619
|
-
* parse
|
|
932
|
+
*
|
|
933
|
+
* // Model the parse failure as an `Err`, everything unexpected as a `Defect`.
|
|
934
|
+
* const parse = fromThrowable(
|
|
935
|
+
* (text: string) => JSON.parse(text) as unknown,
|
|
936
|
+
* (cause, defect) =>
|
|
937
|
+
* cause instanceof SyntaxError ? ("invalid_json" as const) : defect(cause),
|
|
938
|
+
* );
|
|
939
|
+
*
|
|
940
|
+
* parse('{"ok":true}').unwrapOr(null); // => { ok: true }
|
|
941
|
+
* parse("nope"); // => Err("invalid_json")
|
|
620
942
|
* ```
|
|
621
943
|
*/
|
|
622
944
|
declare function fromThrowable<A extends unknown[], T, R>(fn: (...args: A) => T, qualify: (cause: unknown, defect: (cause: unknown) => Defect) => R): (...args: A) => Result$1<T, Exclude<R, Defect>>;
|
|
@@ -642,12 +964,19 @@ declare function fromThrowable<A extends unknown[], T, R>(fn: (...args: A) => T,
|
|
|
642
964
|
* @param qualify - triages a rejection `cause` into a modeled `E`, or marks it
|
|
643
965
|
* unmodeled by returning `defect(cause)` (the helper passed as its second arg).
|
|
644
966
|
*
|
|
967
|
+
* @category Interop
|
|
968
|
+
*
|
|
645
969
|
* @example
|
|
646
970
|
* ```ts
|
|
647
971
|
* import { fromPromise } from "unthrown";
|
|
972
|
+
*
|
|
973
|
+
* // A rejection with a NotFoundError becomes a modeled `Err`; anything else a Defect.
|
|
648
974
|
* const user = await fromPromise(fetchUser(id), (cause, defect) =>
|
|
649
975
|
* cause instanceof NotFoundError ? ("not_found" as const) : defect(cause),
|
|
650
976
|
* );
|
|
977
|
+
*
|
|
978
|
+
* if (user.isOk()) user.value; // => the fetched user
|
|
979
|
+
* // when fetchUser rejects with NotFoundError: user is Err("not_found")
|
|
651
980
|
* ```
|
|
652
981
|
*/
|
|
653
982
|
declare function fromPromise<T, R>(promise: Promise<T> | (() => Promise<T>), qualify: (cause: unknown, defect: (cause: unknown) => Defect) => R): AsyncResult$1<T, Exclude<R, Defect>>;
|
|
@@ -662,6 +991,17 @@ declare function fromPromise<T, R>(promise: Promise<T> | (() => Promise<T>), qua
|
|
|
662
991
|
*
|
|
663
992
|
* @typeParam T - the resolved value type.
|
|
664
993
|
* @param promise - the promise, or a thunk returning one.
|
|
994
|
+
*
|
|
995
|
+
* @category Interop
|
|
996
|
+
*
|
|
997
|
+
* @example
|
|
998
|
+
* ```ts
|
|
999
|
+
* import { fromSafePromise } from "unthrown";
|
|
1000
|
+
*
|
|
1001
|
+
* (await fromSafePromise(Promise.resolve(3))).unwrap(); // => 3
|
|
1002
|
+
* // a rejection becomes a Defect (never a modeled Err):
|
|
1003
|
+
* await fromSafePromise(Promise.reject(new Error("boom"))); // => Defect(Error("boom"))
|
|
1004
|
+
* ```
|
|
665
1005
|
*/
|
|
666
1006
|
declare function fromSafePromise<T>(promise: Promise<T> | (() => Promise<T>)): AsyncResult$1<T, never>;
|
|
667
1007
|
/**
|
|
@@ -698,11 +1038,14 @@ type AsyncResultRecord = Record<string, AsyncResult$1<unknown, unknown>>;
|
|
|
698
1038
|
* collapses to `Result<T[], E>` with no cast. For a **record** keyed by name,
|
|
699
1039
|
* use {@link allFromDict}.
|
|
700
1040
|
*
|
|
1041
|
+
* @category Aggregate
|
|
1042
|
+
*
|
|
701
1043
|
* @example
|
|
702
1044
|
* ```ts
|
|
703
|
-
* import { all, Ok } from "unthrown";
|
|
704
|
-
*
|
|
705
|
-
* all([Ok(1), Ok(
|
|
1045
|
+
* import { all, Ok, Err } from "unthrown";
|
|
1046
|
+
*
|
|
1047
|
+
* all([Ok(1), Ok("a"), Ok(true)]).unwrap(); // => [1, "a", true] (typed [number, string, boolean])
|
|
1048
|
+
* all([Ok(1), Err("e"), Ok(3)]); // => Err("e") (short-circuits on the first Err)
|
|
706
1049
|
* ```
|
|
707
1050
|
*/
|
|
708
1051
|
declare function all<Rs extends readonly Result$1<unknown, unknown>[]>(results: readonly [...Rs]): Result$1<AllOk<Rs, { [K in keyof Rs]: OkOf<Rs[K]> }>, ErrOf<Rs[number]>>;
|
|
@@ -716,10 +1059,14 @@ declare function all<Rs extends readonly Result$1<unknown, unknown>[]>(results:
|
|
|
716
1059
|
* Same folding rules as {@link all}: first `Err` short-circuits, any `Defect`
|
|
717
1060
|
* dominates. This is **not** error accumulation.
|
|
718
1061
|
*
|
|
1062
|
+
* @category Aggregate
|
|
1063
|
+
*
|
|
719
1064
|
* @example
|
|
720
1065
|
* ```ts
|
|
721
|
-
* import { allFromDict, Ok } from "unthrown";
|
|
722
|
-
*
|
|
1066
|
+
* import { allFromDict, Ok, Err } from "unthrown";
|
|
1067
|
+
*
|
|
1068
|
+
* allFromDict({ id: Ok(1), name: Ok("ada") }).unwrap(); // => { id: 1, name: "ada" }
|
|
1069
|
+
* allFromDict({ id: Ok(1), name: Err("missing") }); // => Err("missing")
|
|
723
1070
|
* ```
|
|
724
1071
|
*/
|
|
725
1072
|
declare function allFromDict<R extends ResultRecord>(results: R): Result$1<{ [K in keyof R]: OkOf<R[K]> }, ErrOf<R[keyof R]>>;
|
|
@@ -733,10 +1080,14 @@ declare function allFromDict<R extends ResultRecord>(results: R): Result$1<{ [K
|
|
|
733
1080
|
* short-circuits, any `Defect` dominates. As ever, the returned `AsyncResult`'s
|
|
734
1081
|
* internal promise never rejects. For a **record**, use {@link allFromDictAsync}.
|
|
735
1082
|
*
|
|
1083
|
+
* @category Aggregate
|
|
1084
|
+
*
|
|
736
1085
|
* @example
|
|
737
1086
|
* ```ts
|
|
738
1087
|
* import { allAsync, fromSafePromise } from "unthrown";
|
|
739
|
-
*
|
|
1088
|
+
*
|
|
1089
|
+
* const both = allAsync([fromSafePromise(Promise.resolve(1)), fromSafePromise(Promise.resolve(2))]);
|
|
1090
|
+
* (await both).unwrap(); // => [1, 2]
|
|
740
1091
|
* ```
|
|
741
1092
|
*/
|
|
742
1093
|
declare function allAsync<Rs extends readonly AsyncResult$1<unknown, unknown>[]>(results: readonly [...Rs]): AsyncResult$1<AllOk<Rs, { [K in keyof Rs]: AsyncOkOf<Rs[K]> }>, AsyncErrOf<Rs[number]>>;
|
|
@@ -748,10 +1099,17 @@ declare function allAsync<Rs extends readonly AsyncResult$1<unknown, unknown>[]>
|
|
|
748
1099
|
* Resolved concurrently (order preserved), folded with the {@link all} rules,
|
|
749
1100
|
* and the internal promise never rejects.
|
|
750
1101
|
*
|
|
1102
|
+
* @category Aggregate
|
|
1103
|
+
*
|
|
751
1104
|
* @example
|
|
752
1105
|
* ```ts
|
|
753
1106
|
* import { allFromDictAsync, fromSafePromise } from "unthrown";
|
|
754
|
-
*
|
|
1107
|
+
*
|
|
1108
|
+
* const both = allFromDictAsync({
|
|
1109
|
+
* a: fromSafePromise(Promise.resolve(1)),
|
|
1110
|
+
* b: fromSafePromise(Promise.resolve("x")),
|
|
1111
|
+
* });
|
|
1112
|
+
* (await both).unwrap(); // => { a: 1, b: "x" }
|
|
755
1113
|
* ```
|
|
756
1114
|
*/
|
|
757
1115
|
declare function allFromDictAsync<R extends AsyncResultRecord>(results: R): AsyncResult$1<{ [K in keyof R]: AsyncOkOf<R[K]> }, AsyncErrOf<R[keyof R]>>;
|
|
@@ -774,10 +1132,12 @@ declare function allFromDictAsync<R extends AsyncResultRecord>(results: R): Asyn
|
|
|
774
1132
|
* (`AsyncResult.fromPromise`, `AsyncResult.all`, …), grouped by what they
|
|
775
1133
|
* return — a static lives in exactly one namespace.
|
|
776
1134
|
*
|
|
1135
|
+
* @category Facade
|
|
1136
|
+
*
|
|
777
1137
|
* @example
|
|
778
1138
|
* ```ts
|
|
779
1139
|
* import { Result } from "unthrown";
|
|
780
|
-
* Result.Ok(1).flatMap((n) => Result.Ok(n + 1)).unwrap(); // 2
|
|
1140
|
+
* Result.Ok(1).flatMap((n) => Result.Ok(n + 1)).unwrap(); // => 2
|
|
781
1141
|
* ```
|
|
782
1142
|
*/
|
|
783
1143
|
declare const Result: {
|
|
@@ -793,6 +1153,20 @@ declare const Result: {
|
|
|
793
1153
|
readonly isDefect: typeof isDefect;
|
|
794
1154
|
readonly isResult: typeof isResult;
|
|
795
1155
|
};
|
|
1156
|
+
/**
|
|
1157
|
+
* `Result<T, E>` — the core discriminated union. Shares its name with the
|
|
1158
|
+
* {@link Result | companion object} above (the value and type are one name); this
|
|
1159
|
+
* is the type half.
|
|
1160
|
+
*
|
|
1161
|
+
* @remarks
|
|
1162
|
+
* A `Result` is a discriminated union, so TypeDoc can't list its methods on this
|
|
1163
|
+
* alias. Its fluent combinators (`map`, `flatMap`, `match`, `unwrap`, …) are
|
|
1164
|
+
* documented one per entry on {@link ResultMethods} — the shared method surface
|
|
1165
|
+
* every variant carries. For "which one do I reach for?", see the
|
|
1166
|
+
* [Choosing a combinator](/guide/choosing-a-combinator) guide.
|
|
1167
|
+
*
|
|
1168
|
+
* @category Facade
|
|
1169
|
+
*/
|
|
796
1170
|
type Result<T, E> = Result$1<T, E>;
|
|
797
1171
|
/**
|
|
798
1172
|
* Companion object grouping the **`AsyncResult`-producing** entry points under
|
|
@@ -809,10 +1183,13 @@ type Result<T, E> = Result$1<T, E>;
|
|
|
809
1183
|
* {@link Result}, the free functions remain the primary, tree-shakeable API; the
|
|
810
1184
|
* value `AsyncResult` and the type {@link AsyncResult} share one name.
|
|
811
1185
|
*
|
|
1186
|
+
* @category Facade
|
|
1187
|
+
*
|
|
812
1188
|
* @example
|
|
813
1189
|
* ```ts
|
|
814
1190
|
* import { AsyncResult } from "unthrown";
|
|
815
1191
|
* const user = await AsyncResult.fromPromise(fetchUser(id), (c, defect) => defect(c));
|
|
1192
|
+
* user.unwrap(); // => the fetched user (on success)
|
|
816
1193
|
* ```
|
|
817
1194
|
*/
|
|
818
1195
|
declare const AsyncResult: {
|
|
@@ -821,6 +1198,19 @@ declare const AsyncResult: {
|
|
|
821
1198
|
readonly all: typeof allAsync;
|
|
822
1199
|
readonly allFromDict: typeof allFromDictAsync;
|
|
823
1200
|
};
|
|
1201
|
+
/**
|
|
1202
|
+
* `AsyncResult<T, E>` — the async counterpart of {@link Result}. Shares its name
|
|
1203
|
+
* with the {@link AsyncResult | companion object} above (value and type are one
|
|
1204
|
+
* name); this is the type half.
|
|
1205
|
+
*
|
|
1206
|
+
* @remarks
|
|
1207
|
+
* `AsyncResult` carries the async fluent surface; its combinators (`map`,
|
|
1208
|
+
* `flatMap`, `match`, `unwrap`, …) are documented one per entry — with their
|
|
1209
|
+
* async signatures — on {@link AsyncResultMethods}. For "which one do I reach
|
|
1210
|
+
* for?", see the [Choosing a combinator](/guide/choosing-a-combinator) guide.
|
|
1211
|
+
*
|
|
1212
|
+
* @category Facade
|
|
1213
|
+
*/
|
|
824
1214
|
type AsyncResult<T, E> = AsyncResult$1<T, E>;
|
|
825
1215
|
//#endregion
|
|
826
1216
|
//#region src/tagged.d.ts
|
|
@@ -831,8 +1221,10 @@ type Props = Record<string, unknown>;
|
|
|
831
1221
|
*
|
|
832
1222
|
* @typeParam Tag - the string literal discriminant.
|
|
833
1223
|
* @typeParam A - the payload object type.
|
|
1224
|
+
*
|
|
1225
|
+
* @category Types
|
|
834
1226
|
*/
|
|
835
|
-
type TaggedErrorInstance<Tag extends string, A extends Props> = Error & Readonly<A
|
|
1227
|
+
type TaggedErrorInstance<Tag extends string, A extends Props> = Error & Readonly<Omit<A, "name" | "message">> & {
|
|
836
1228
|
readonly _tag: Tag;
|
|
837
1229
|
};
|
|
838
1230
|
/**
|
|
@@ -841,12 +1233,23 @@ type TaggedErrorInstance<Tag extends string, A extends Props> = Error & Readonly
|
|
|
841
1233
|
*
|
|
842
1234
|
* @remarks
|
|
843
1235
|
* When the payload is empty, the constructor takes **no** arguments (the
|
|
844
|
-
* `keyof A extends never ? void : A` trick); otherwise it takes the payload.
|
|
1236
|
+
* `keyof A extends never ? void : A` trick); otherwise it takes the payload. The
|
|
1237
|
+
* `name` and `message` keys are both **rejected** (`name?: never` /
|
|
1238
|
+
* `message?: never`) because both are reserved: `name` is the display label, and
|
|
1239
|
+
* `message` is the human string owned by `Error`. Set the message the standard
|
|
1240
|
+
* way — `override message = "…"` (or a constructor override) on the subclass —
|
|
1241
|
+
* never as a free-form per-call payload field. The reservations are enforced at
|
|
1242
|
+
* the call site, mirroring how {@link TaggedErrorInstance} excludes both.
|
|
845
1243
|
*
|
|
846
1244
|
* @typeParam Tag - the string literal discriminant.
|
|
1245
|
+
*
|
|
1246
|
+
* @category Types
|
|
847
1247
|
*/
|
|
848
1248
|
type TaggedErrorConstructor<Tag extends string> = {
|
|
849
|
-
new <A extends Props = {}>(args: keyof A extends never ? void : A
|
|
1249
|
+
new <A extends Props = {}>(args: keyof A extends never ? void : A & {
|
|
1250
|
+
readonly name?: never;
|
|
1251
|
+
readonly message?: never;
|
|
1252
|
+
}): TaggedErrorInstance<Tag, A>;
|
|
850
1253
|
};
|
|
851
1254
|
/**
|
|
852
1255
|
* Build a base class for a tagged error — a class extending `Error` with a
|
|
@@ -854,9 +1257,17 @@ type TaggedErrorConstructor<Tag extends string> = {
|
|
|
854
1257
|
*
|
|
855
1258
|
* @remarks
|
|
856
1259
|
* Extend the returned class to declare a concrete error. Supply the payload with
|
|
857
|
-
* an instantiation expression; omit it for a payload-less error.
|
|
858
|
-
*
|
|
859
|
-
*
|
|
1260
|
+
* an instantiation expression; omit it for a payload-less error. The `message`
|
|
1261
|
+
* is **not** a payload field — it is the human string owned by `Error`, not
|
|
1262
|
+
* structured data, so it is reserved. Define it once per subclass the standard
|
|
1263
|
+
* way, `override message = "…"` (it may interpolate the payload via `this`,
|
|
1264
|
+
* which the base populates before the subclass field initialiser runs); a
|
|
1265
|
+
* payload `message` is rejected at compile time, so contextual detail lives in
|
|
1266
|
+
* typed fields, never baked into per-call prose. The `_tag` always reflects
|
|
1267
|
+
* `tag` and cannot be overridden by the payload. `name` is likewise reserved —
|
|
1268
|
+
* it is the display label (set it with `options.name`); a payload `name` is
|
|
1269
|
+
* rejected at compile time (and excluded from the instance type), so it can't
|
|
1270
|
+
* shadow `Error.name`.
|
|
860
1271
|
*
|
|
861
1272
|
* `_tag` is the discriminant used by {@link matchTags}; `Error.name` is the
|
|
862
1273
|
* human-facing label in stack traces and logs. By default they coincide, but
|
|
@@ -867,11 +1278,14 @@ type TaggedErrorConstructor<Tag extends string> = {
|
|
|
867
1278
|
* ```ts
|
|
868
1279
|
* class RetryableError extends TaggedError("@my-lib/RetryableError", {
|
|
869
1280
|
* name: "RetryableError",
|
|
870
|
-
* })
|
|
1281
|
+
* }) {
|
|
1282
|
+
* override message = "operation failed; safe to retry";
|
|
1283
|
+
* }
|
|
871
1284
|
*
|
|
872
|
-
* const e = new RetryableError(
|
|
873
|
-
* e._tag;
|
|
874
|
-
* e.name;
|
|
1285
|
+
* const e = new RetryableError();
|
|
1286
|
+
* e._tag; // "@my-lib/RetryableError" — namespaced discriminant
|
|
1287
|
+
* e.name; // "RetryableError" — clean display name
|
|
1288
|
+
* e.message; // "operation failed; safe to retry" — the standard Error.message
|
|
875
1289
|
* ```
|
|
876
1290
|
*
|
|
877
1291
|
* @typeParam Tag - the string literal discriminant.
|
|
@@ -879,13 +1293,15 @@ type TaggedErrorConstructor<Tag extends string> = {
|
|
|
879
1293
|
* @param options - optional overrides. `options.name` sets `Error.name`
|
|
880
1294
|
* independently of `tag` (defaults to `tag`).
|
|
881
1295
|
*
|
|
1296
|
+
* @category Tagged errors
|
|
1297
|
+
*
|
|
882
1298
|
* @example
|
|
883
1299
|
* ```ts
|
|
884
1300
|
* class NotFound extends TaggedError("NotFound") {}
|
|
885
1301
|
* class HttpError extends TaggedError("HttpError")<{ status: number }> {}
|
|
886
1302
|
*
|
|
887
|
-
* new NotFound()._tag; // "NotFound"
|
|
888
|
-
* new HttpError({ status: 500 }).status; // 500
|
|
1303
|
+
* new NotFound()._tag; // => "NotFound"
|
|
1304
|
+
* new HttpError({ status: 500 }).status; // => 500
|
|
889
1305
|
* ```
|
|
890
1306
|
*/
|
|
891
1307
|
declare function TaggedError<Tag extends string>(tag: Tag, options?: {
|
|
@@ -899,6 +1315,8 @@ declare function TaggedError<Tag extends string>(tag: Tag, options?: {
|
|
|
899
1315
|
* @typeParam T - the success value type.
|
|
900
1316
|
* @typeParam E - the tagged error union.
|
|
901
1317
|
* @typeParam R - the folded result type.
|
|
1318
|
+
*
|
|
1319
|
+
* @category Types
|
|
902
1320
|
*/
|
|
903
1321
|
type TagHandlers<T, E extends {
|
|
904
1322
|
_tag: string;
|
|
@@ -908,6 +1326,14 @@ type TagHandlers<T, E extends {
|
|
|
908
1326
|
} & { [K in E["_tag"]]: (error: Extract<E, {
|
|
909
1327
|
_tag: K;
|
|
910
1328
|
}>) => R };
|
|
1329
|
+
/**
|
|
1330
|
+
* The channel-handler names are reserved: an error tag named `"Ok"` or
|
|
1331
|
+
* `"Defect"` would collide with them inside {@link TagHandlers}, so
|
|
1332
|
+
* {@link matchTags} rejects such unions at the call site.
|
|
1333
|
+
*
|
|
1334
|
+
* @internal
|
|
1335
|
+
*/
|
|
1336
|
+
type ReservedTagError = 'unthrown: error tags "Ok" and "Defect" are reserved by matchTags — rename the colliding tag (TaggedError\'s options.name can keep the display name)';
|
|
911
1337
|
/**
|
|
912
1338
|
* Exhaustively fold a {@link Result} (or {@link AsyncResult}) whose error type is
|
|
913
1339
|
* a tagged union, dispatching each error to the handler matching its `_tag`.
|
|
@@ -916,7 +1342,10 @@ type TagHandlers<T, E extends {
|
|
|
916
1342
|
* The `handlers` object must provide `Ok`, `Defect`, and exactly one function
|
|
917
1343
|
* per error tag; each tag's handler receives the narrowed error variant. A
|
|
918
1344
|
* missing tag is a compile error. For an `AsyncResult`, the fold resolves to a
|
|
919
|
-
* `Promise<R>`.
|
|
1345
|
+
* `Promise<R>`. At runtime, an error whose `_tag` has no handler (possible only
|
|
1346
|
+
* outside the typed contract) is routed to the `Defect` handler — an unmodeled
|
|
1347
|
+
* tag is an unmodeled failure. Tags named `"Ok"` or `"Defect"` are rejected at
|
|
1348
|
+
* compile time.
|
|
920
1349
|
*
|
|
921
1350
|
* @typeParam T - the success value type.
|
|
922
1351
|
* @typeParam E - the tagged error union (`E extends { _tag: string }`).
|
|
@@ -924,26 +1353,33 @@ type TagHandlers<T, E extends {
|
|
|
924
1353
|
* @param result - the result to fold.
|
|
925
1354
|
* @param handlers - one branch per channel/tag.
|
|
926
1355
|
*
|
|
1356
|
+
* @category Tagged errors
|
|
1357
|
+
*
|
|
927
1358
|
* @example
|
|
928
1359
|
* ```ts
|
|
1360
|
+
* import { Ok, Err, matchTags, TaggedError, type Result } from "unthrown";
|
|
1361
|
+
*
|
|
929
1362
|
* class NotFound extends TaggedError("NotFound") {}
|
|
930
1363
|
* class Forbidden extends TaggedError("Forbidden")<{ user: string }> {}
|
|
931
1364
|
*
|
|
932
|
-
*
|
|
933
|
-
*
|
|
934
|
-
*
|
|
935
|
-
*
|
|
936
|
-
*
|
|
937
|
-
*
|
|
938
|
-
*
|
|
1365
|
+
* const fold = (r: Result<number, NotFound | Forbidden>) =>
|
|
1366
|
+
* matchTags(r, {
|
|
1367
|
+
* Ok: (n) => `got ${n}`,
|
|
1368
|
+
* Defect: (cause) => `bug: ${String(cause)}`,
|
|
1369
|
+
* NotFound: () => "404",
|
|
1370
|
+
* Forbidden: (e) => `403 for ${e.user}`,
|
|
1371
|
+
* });
|
|
1372
|
+
*
|
|
1373
|
+
* fold(Ok(1)); // => "got 1"
|
|
1374
|
+
* fold(Err(new Forbidden({ user: "ada" }))); // => "403 for ada"
|
|
939
1375
|
* ```
|
|
940
1376
|
*/
|
|
941
1377
|
declare function matchTags<T, E extends {
|
|
942
1378
|
_tag: string;
|
|
943
|
-
}, R>(result: Result$1<T, E>, handlers: TagHandlers<T, E, R>): R;
|
|
1379
|
+
}, R>(result: Result$1<T, E>, handlers: TagHandlers<T, E, R> & ([Extract<E["_tag"], "Ok" | "Defect">] extends [never] ? unknown : ReservedTagError)): R;
|
|
944
1380
|
declare function matchTags<T, E extends {
|
|
945
1381
|
_tag: string;
|
|
946
|
-
}, R>(result: AsyncResult$1<T, E>, handlers: TagHandlers<T, E, R>): Promise<R>;
|
|
1382
|
+
}, R>(result: AsyncResult$1<T, E>, handlers: TagHandlers<T, E, R> & ([Extract<E["_tag"], "Ok" | "Defect">] extends [never] ? unknown : ReservedTagError)): Promise<R>;
|
|
947
1383
|
//#endregion
|
|
948
|
-
export { type AsyncErrOf, type AsyncOkOf, AsyncResult, type Awaitable, type DefectView, Do, Err, type ErrOf, type ErrView, Ok, type OkOf, type OkView, Result, type TagHandlers, TaggedError, type TaggedErrorConstructor, type TaggedErrorInstance, UnwrapError, all, allAsync, allFromDict, allFromDictAsync, fromNullable, fromPromise, fromSafePromise, fromThrowable, isDefect, isErr, isOk, isResult, matchTags };
|
|
1384
|
+
export { type AsyncErrOf, type AsyncOkOf, AsyncResult, type AsyncResultMethods, type Awaitable, type DefectView, Do, Err, type ErrOf, type ErrView, type NotThenable, Ok, type OkOf, type OkView, Result, type ResultMethods, type TagHandlers, TaggedError, type TaggedErrorConstructor, type TaggedErrorInstance, UnwrapError, all, allAsync, allFromDict, allFromDictAsync, fromNullable, fromPromise, fromSafePromise, fromThrowable, isDefect, isErr, isOk, isResult, matchTags };
|
|
949
1385
|
//# sourceMappingURL=index.d.cts.map
|