retuple 1.0.0-next.2 → 1.0.0-next.20

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/dist/index.d.ts CHANGED
@@ -1,75 +1,153 @@
1
- export type Ok<T> = OkTuple<T> & Retuple<T, never>;
2
- export type Err<E> = ErrTuple<E> & Retuple<never, E>;
1
+ import { type ResultLike } from "retuple-symbols";
2
+ export type Ok = typeof Ok;
3
+ export type Err = typeof Err;
3
4
  export type Result<T, E> = (OkTuple<T> | ErrTuple<E>) & Retuple<T, E>;
4
- export { type ResultAsync };
5
- export declare class RetupleUnwrapFailed<E = unknown> extends Error {
5
+ export { type ResultAsync, type ResultRetry };
6
+ export interface ResultRetryController<E> {
7
+ error: E;
8
+ attempt: number;
9
+ abort: () => void;
10
+ }
11
+ /**
12
+ * ## Retuple Unwrap Failed
13
+ *
14
+ * An error which occurs when calling `$unwrap` on `Err`.
15
+ */
16
+ export declare class RetupleUnwrapFailed<const E = unknown> extends Error {
6
17
  value: E;
7
18
  constructor(value: E, msg?: string);
8
19
  }
9
- export declare class RetupleUnwrapErrFailed<T = unknown> extends Error {
20
+ /**
21
+ * ## Retuple Unwrap Err Failed
22
+ *
23
+ * An error which occurs when calling `$unwrapErr` on `Ok`.
24
+ */
25
+ export declare class RetupleUnwrapErrFailed<const T = unknown> extends Error {
10
26
  value: T;
11
27
  constructor(value: T, msg?: string);
12
28
  }
13
- export declare class RetupleExpectFailed<E = unknown> extends Error {
29
+ /**
30
+ * ## Retuple Expect Failed
31
+ *
32
+ * An error which occurs when calling `$expect` on `Err`, when the value
33
+ * contained in the `Err` is not an instance of `Error`.
34
+ */
35
+ export declare class RetupleExpectFailed<const E = unknown> extends Error {
14
36
  value: E;
15
37
  constructor(value: E);
16
38
  }
17
- export declare class RetupleThrownValueError extends Error {
39
+ /**
40
+ * ## Retuple Thrown Value Error
41
+ *
42
+ * An error constructed when a safe function call throws or rejects, when the
43
+ * thrown error or rejected value is not an instance of `Error`, and when no
44
+ * map error function is provided.
45
+ */
46
+ export declare class RetupleCaughtValueError extends Error {
18
47
  value: unknown;
19
48
  constructor(value: unknown);
20
49
  }
21
50
  /**
22
- * ## Result
51
+ * ## Retuple Invalid Union Error
23
52
  *
24
- * @TODO
53
+ * This error is thrown when attempting to construct a `Result` from a
54
+ * discriminated union, when the 'success' property is not boolean. In this
55
+ * case, it is impossible to determine whether the result should be `Ok` or
56
+ * `Err`.
25
57
  */
26
- export declare const Result: {
27
- Ok: typeof Ok;
28
- Err: typeof Err;
29
- from: typeof from;
30
- safe: typeof safe;
31
- safeAsync: typeof safeAsync;
32
- safePromise: typeof safePromise;
33
- };
34
- export default Result;
58
+ export declare class RetupleInvalidUnionError extends Error {
59
+ value: unknown;
60
+ constructor(value: unknown);
61
+ }
35
62
  /**
36
- * ## Ok
63
+ * ## Retuple Array Method Unavailable Error
37
64
  *
38
- * @TODO
65
+ * This error is thrown when calling a built-in array method from a `Result`.
39
66
  */
40
- export declare function Ok(): Ok<void>;
41
- export declare function Ok<T>(val: T): Ok<T>;
67
+ export declare class RetupleArrayMethodUnavailableError extends Error {
68
+ value: unknown[];
69
+ constructor(value: unknown[], method: Exclude<keyof any[] & string, "length">);
70
+ }
42
71
  /**
43
- * ## Err
72
+ * ## Result
44
73
  *
45
74
  * @TODO
46
75
  */
47
- export declare function Err(): Err<void>;
48
- export declare function Err<E>(err: E): Err<E>;
49
- /**
50
- * Construct a {@link Result} from a value. If the value is truthy, the result
51
- * is `Ok`.
52
- */
53
- export declare function from<T>(value: T): Result<Truthy<T>, true>;
54
- export declare function from<T, E>(value: T, error: () => E): Result<Truthy<T>, E>;
55
- /**
56
- * Construct a {@link Result} from a synchronous function call. If the function
57
- * returns without throwing, the result is `Ok`.
58
- */
59
- export declare function safe<T>(f: () => Awaited<T>): Result<T, Error>;
60
- export declare function safe<T, E>(f: () => Awaited<T>, mapError: (err: unknown) => E): Result<T, E>;
76
+ export declare function Result<T, E>(resultLike: ResultLike<T, E>): Result<T, E>;
77
+ export declare namespace Result {
78
+ var Ok: typeof import(".").Ok;
79
+ var Err: typeof import(".").Err;
80
+ var $from: <T, E>(result: ResultLike<T, E>) => Result<T, E>;
81
+ var $resolve: <T, E>(result: ResultLikeAwaitable<T, E>) => ResultAsync<T, E>;
82
+ var $nonNullable: {
83
+ <const T>(value: T): Result<NonNullable<T>, true>;
84
+ <const T, E>(value: T, error: () => E): Result<NonNullable<T>, E>;
85
+ };
86
+ var $truthy: {
87
+ <const T>(value: T): Result<Truthy<T>, true>;
88
+ <const T, E>(value: T, error: () => E): Result<Truthy<T>, E>;
89
+ };
90
+ var $fromUnion: <U extends ObjectUnionOk<any> | ObjectUnionErr<any>>(union: U) => Result<U extends ObjectUnionOk<infer T> ? T : never, U extends ObjectUnionErr<infer E> ? E : never>;
91
+ var $safe: {
92
+ <T>(f: () => Awaited<T>): Result<T, Error>;
93
+ <T, E>(f: () => Awaited<T>, mapError: (err: unknown) => E): Result<T, E>;
94
+ };
95
+ var $safeAsync: {
96
+ <T>(f: () => T | PromiseLike<T>): ResultAsync<T, Error>;
97
+ <T, E>(f: () => T | PromiseLike<T>, mapError: (err: unknown) => E): ResultAsync<T, E>;
98
+ };
99
+ var $safePromise: {
100
+ <T>(promise: PromiseLike<T>): ResultAsync<T, Error>;
101
+ <T, E>(promise: PromiseLike<T>, mapError: (err: unknown) => E): ResultAsync<T, E>;
102
+ };
103
+ var $retry: <T, E>(f: () => ResultLike<T, E> | PromiseLike<ResultLike<T, E>>) => ResultRetry<T, E>;
104
+ var $safeRetry: {
105
+ <T>(f: () => T | PromiseLike<T>): ResultRetry<T, Error>;
106
+ <T, E>(f: () => T | PromiseLike<T>, mapError: (err: unknown) => E): ResultRetry<T, E>;
107
+ };
108
+ }
61
109
  /**
62
- * Construct a {@link ResultAsync} from a function call. If the function returns
63
- * without throwing, and any promise returned resolves, the result is `Ok`.
110
+ * Create a new {@link Result} with the `Ok` variant. When called without
111
+ * arguments the `T` type is `void`.
112
+ *
113
+ * @example
114
+ *
115
+ * ```ts
116
+ * const [err, value] = Ok("test");
117
+ *
118
+ * assert.equal(err, undefined);
119
+ * assert.equal(value, "test");
120
+ * ```
121
+ *
122
+ * @example
123
+ *
124
+ * ```ts
125
+ * const result: Result<void, never> = Ok();
126
+ * ```
64
127
  */
65
- export declare function safeAsync<T>(f: () => T | PromiseLike<T>): ResultAsync<T, Error>;
66
- export declare function safeAsync<T, E>(f: () => T | PromiseLike<T>, mapError: (err: unknown) => E): ResultAsync<T, E>;
128
+ export declare function Ok(): Result<void, never>;
129
+ export declare function Ok<const T>(val: T): Result<T, never>;
67
130
  /**
68
- * Construct a {@link Result} from a promise. If the promise resolves, the
69
- * result is `Ok`.
131
+ * Create a new {@link Result} with the `Err` variant. When called without
132
+ * arguments the `E` type is `void`.
133
+ *
134
+ * @example
135
+ *
136
+ * ```ts
137
+ * const [err, value] = Err("test");
138
+ *
139
+ * assert.equal(err, "test");
140
+ * assert.equal(value, undefined);
141
+ * ```
142
+ *
143
+ * @example
144
+ *
145
+ * ```ts
146
+ * const result: Result<never, void> = Err();
147
+ * ```
70
148
  */
71
- export declare function safePromise<T>(promise: PromiseLike<T>): ResultAsync<T, Error>;
72
- export declare function safePromise<T, E>(promise: PromiseLike<T>, mapError: (err: unknown) => E): ResultAsync<T, E>;
149
+ export declare function Err(): Result<never, void>;
150
+ export declare function Err<const E>(err: E): Result<never, E>;
73
151
  /**
74
152
  * ## ResultAsync
75
153
  *
@@ -78,340 +156,1317 @@ export declare function safePromise<T, E>(promise: PromiseLike<T>, mapError: (er
78
156
  declare class ResultAsync<T, E> {
79
157
  #private;
80
158
  constructor(inner: PromiseLike<Result<T, E>>);
81
- then<TResult1 = Result<T, E>, TResult2 = never>(onfulfilled?: ((result: Result<T, E>) => TResult1 | PromiseLike<TResult1>) | null, onrejected?: (reason: any) => TResult2 | PromiseLike<TResult2>): PromiseLike<TResult1 | TResult2>;
82
- /**
83
- * @TODO
84
- */
85
- $value(this: ResultAsync<T, E>): Promise<T | E>;
159
+ then<U = Result<T, E>, F = never>(onfulfilled?: ((value: Result<T, E>) => U | PromiseLike<U>) | null | undefined, onrejected?: ((reason: any) => F | PromiseLike<F>) | null | undefined): PromiseLike<U | F>;
86
160
  /**
87
- * @TODO
161
+ * The same as {@link Retuple.$expect|$expect}, except it returns a `Promise`.
88
162
  */
89
163
  $expect(this: ResultAsync<T, Error>): Promise<T>;
90
164
  /**
91
- * @TODO
165
+ * The same as {@link Retuple.$unwrap|$unwrap}, except it returns a `Promise`.
92
166
  */
93
167
  $unwrap(this: ResultAsync<T, E>, msg?: string): Promise<T>;
94
168
  /**
95
- * @TODO
169
+ * The same as {@link Retuple.$unwrapErr|$unwrapErr}, except it returns
170
+ * a `Promise`.
96
171
  */
97
172
  $unwrapErr(this: ResultAsync<T, E>, msg?: string): Promise<E>;
98
173
  /**
99
- * @TODO
174
+ * The same as {@link Retuple.$unwrapOr|$unwrapOr}, except it returns
175
+ * a `Promise`.
100
176
  */
101
- $unwrapOr<U>(this: ResultAsync<T, E>, def: U): Promise<T | U>;
177
+ $unwrapOr<const U = T>(this: ResultAsync<T, E>, def: U): Promise<T | U>;
102
178
  /**
103
- * @TODO
179
+ * The same as {@link Retuple.$unwrapOrElse|$unwrapOrElse}, except it returns
180
+ * a `Promise`.
104
181
  */
105
182
  $unwrapOrElse<U = T>(this: ResultAsync<T, E>, f: () => U): Promise<T | U>;
106
183
  /**
107
- * @TODO
184
+ * The same as {@link Retuple.$map|$map}, except it returns
185
+ * {@link ResultAsync}.
108
186
  */
109
187
  $map<U>(this: ResultAsync<T, E>, f: (val: T) => U): ResultAsync<U, E>;
110
188
  /**
111
- * @TODO
189
+ * The same as {@link Retuple.$mapErr|$mapErr}, except it returns
190
+ * {@link ResultAsync}.
112
191
  */
113
- $mapErr<F>(this: ResultAsync<T, E>, f: (err: E) => F): ResultAsync<T, F>;
192
+ $mapErr<F = E>(this: ResultAsync<T, E>, f: (err: E) => F): ResultAsync<T, F>;
114
193
  /**
115
- * @TODO
194
+ * The same as {@link Retuple.$mapOr|$mapOr}, except it returns
195
+ * {@link ResultAsync}.
116
196
  */
117
- $mapOr<U>(this: ResultAsync<T, E>, def: U, f: (val: T) => U): ResultAsync<U, E>;
197
+ $mapOr<U, V = U>(this: ResultAsync<T, E>, def: U, f: (val: T) => V): ResultAsync<U | V, never>;
118
198
  /**
119
- * @TODO
199
+ * The same as {@link Retuple.$mapOrElse|$mapOrElse}, except it returns
200
+ * {@link ResultAsync}.
120
201
  */
121
- $mapOrElse<U>(this: ResultAsync<T, E>, def: (err: E) => U, f: (val: T) => U): ResultAsync<U, E>;
202
+ $mapOrElse<U, V = U>(this: ResultAsync<T, E>, def: (err: E) => U, f: (val: T) => V): ResultAsync<U | V, never>;
122
203
  /**
123
- * @TODO
204
+ * The same as {@link Retuple.$andAssertOr|$andAssertOr}, except it:
205
+ *
206
+ * - can also accept a `PromiseLike` default value;
207
+ * - returns {@link ResultAsync}.
124
208
  */
125
- $or<U = T, F = E>(this: ResultAsync<T, E>, or: Result<U, F> | PromiseLike<Result<U, F>>): ResultAsync<T | U, E | F>;
209
+ $andAssertOr<U = T, F = E>(this: ResultAsync<T, E>, def: ResultLikeAwaitable<U, F>): ResultAsync<Truthy<T> | U, E | F>;
210
+ $andAssertOr<U = T, F = E, A extends T = T>(this: ResultAsync<T, E>, def: ResultLikeAwaitable<U, F>, predicate: (val: T) => val is A): ResultAsync<U | A, E | F>;
211
+ $andAssertOr<U = T, F = E>(this: ResultAsync<T, E>, def: ResultLikeAwaitable<U, F>, condition: (val: T) => unknown): ResultAsync<T | U, E | F>;
126
212
  /**
127
- * @TODO
213
+ * The same as {@link Retuple.$andAssertOrElse|$andAssertOrElse}, except it:
214
+ *
215
+ * - can also accept an `async` default function;
216
+ * - returns {@link ResultAsync}.
128
217
  */
129
- $orElse<U = T, F = E>(this: ResultAsync<T, E>, f: (err: E) => Result<U, F> | PromiseLike<Result<U, F>>): ResultAsync<T | U, E | F>;
218
+ $andAssertOrElse<U = T, F = E>(this: ResultAsync<T, E>, def: (val: T) => ResultLikeAwaitable<U, F>): ResultAsync<Truthy<T> | U, E | F>;
219
+ $andAssertOrElse<U = T, F = E, A extends T = T>(this: ResultAsync<T, E>, def: (val: T) => ResultLikeAwaitable<U, F>, predicate: (val: T) => val is A): ResultAsync<U | A, E | F>;
220
+ $andAssertOrElse<U = T, F = E>(this: ResultAsync<T, E>, def: (val: T) => ResultLikeAwaitable<U, F>, condition: (val: T) => unknown): ResultAsync<T | U, E | F>;
130
221
  /**
131
- * @TODO
222
+ * The same as {@link Retuple.$or|$or}, except it:
223
+ *
224
+ * - can also accept a `PromiseLike` or value;
225
+ * - returns {@link ResultAsync}.
132
226
  */
133
- $orSafe<U = T, F = Error>(this: ResultAsync<T, E>, f: (err: E) => U | PromiseLike<U>, mapError?: (err: unknown) => F): ResultAsync<T | U, E | F>;
227
+ $or<U = T, F = E>(this: ResultAsync<T, E>, or: ResultLikeAwaitable<U, F>): ResultAsync<T | U, F>;
134
228
  /**
135
- * @TODO
229
+ * The same as {@link Retuple.$orElse|$orElse}, except it:
230
+ *
231
+ * - can also accept an `async` or function;
232
+ * - returns {@link ResultAsync}.
136
233
  */
137
- $and<U = T, F = E>(this: ResultAsync<T, E>, and: Result<U, F> | PromiseLike<Result<U, F>>): ResultAsync<U, E | F>;
234
+ $orElse<U = T, F = E>(this: ResultAsync<T, E>, f: (err: E) => ResultLikeAwaitable<U, F>): ResultAsync<T | U, F>;
138
235
  /**
139
- * @TODO
236
+ * The same as {@link Retuple.$orSafe|$orSafe}, except it:
237
+ *
238
+ * - can also accept an `async` safe function;
239
+ * - returns {@link ResultAsync}.
140
240
  */
141
- $andThen<U = T, F = E>(this: ResultAsync<T, E>, f: (val: T) => Result<U, F> | PromiseLike<Result<U, F>>): ResultAsync<U, E | F>;
241
+ $orSafe<U = T>(this: ResultAsync<T, E>, f: (err: E) => U | PromiseLike<U>): ResultAsync<T | U, Error>;
242
+ $orSafe<U = T, F = E>(this: ResultAsync<T, E>, f: (err: E) => U | PromiseLike<U>, mapError: (err: unknown) => F): ResultAsync<T | U, F>;
142
243
  /**
143
- * @TODO
244
+ * Returns {@link ResultAsync} based on the outcome of the promise when this
245
+ * result is `Err`.
246
+ *
247
+ * Otherwise, returns `Ok` containing the current contained value.
248
+ *
249
+ * Uses the same strategy as {@link Result.$safePromise}, equivalent to
250
+ * calling:
251
+ *
252
+ * ```ts
253
+ * resultAsync.$orElse(() => Result.$safePromise(...))
254
+ * ```
144
255
  */
145
- $andThrough<F = E>(this: ResultAsync<T, E>, f: (val: T) => Result<any, F> | PromiseLike<Result<any, F>>): ResultAsync<T, E | F>;
256
+ $orSafePromise<U = T>(this: ResultAsync<T, E>, promise: PromiseLike<U>): ResultAsync<T | U, Error>;
257
+ $orSafePromise<U = T, F = E>(this: ResultAsync<T, E>, promise: PromiseLike<U>, mapError: (err: unknown) => F): ResultAsync<T | U, F>;
146
258
  /**
147
- * @TODO
259
+ * The same as {@link Retuple.$and|$and}, except it:
260
+ *
261
+ * - can also accept a `PromiseLike` and value;
262
+ * - returns {@link ResultAsync}.
148
263
  */
149
- $andSafe<U = T, F = Error>(this: ResultAsync<T, E>, f: (val: T) => U | PromiseLike<U>, mapError?: (err: unknown) => F): ResultAsync<U, E | F>;
264
+ $and<U = T, F = E>(this: ResultAsync<T, E>, and: ResultLikeAwaitable<U, F>): ResultAsync<U, E | F>;
150
265
  /**
151
- * @TODO
266
+ * The same as {@link Retuple.$andThen|$andThen}, except it:
267
+ *
268
+ * - can also accept an `async` and function;
269
+ * - returns {@link ResultAsync}.
152
270
  */
153
- $peek(this: ResultAsync<T, E>, f: (res: Result<T, E>) => any): ResultAsync<T, E>;
271
+ $andThen<U = T, F = E>(this: ResultAsync<T, E>, f: (val: T) => ResultLikeAwaitable<U, F>): ResultAsync<U, E | F>;
154
272
  /**
155
- * @TODO
273
+ * The same as {@link Retuple.$andThrough|$andThrough}, except it:
274
+ *
275
+ * - can also accept an `async` through function;
276
+ * - returns {@link ResultAsync}.
156
277
  */
157
- $tap(this: ResultAsync<T, E>, f: (val: T) => any): ResultAsync<T, E>;
278
+ $andThrough<F = E>(this: ResultAsync<T, E>, f: (val: T) => ResultLikeAwaitable<any, F>): ResultAsync<T, E | F>;
158
279
  /**
159
- * @TODO
280
+ * The same as {@link Retuple.$andSafe|$andSafe}, except it:
281
+ *
282
+ * - can also accept an `async` safe function;
283
+ * - returns {@link ResultAsync}.
160
284
  */
161
- $tapErr(this: ResultAsync<T, E>, f: (err: E) => any): ResultAsync<T, E>;
285
+ $andSafe<U = T>(this: ResultAsync<T, E>, f: (val: T) => U | PromiseLike<U>): ResultAsync<U, E | Error>;
286
+ $andSafe<U = T, F = E>(this: ResultAsync<T, E>, f: (val: T) => U | PromiseLike<U>, mapError: (err: unknown) => F): ResultAsync<U, E | F>;
162
287
  /**
163
- * @TODO
288
+ * Returns {@link ResultAsync} based on the outcome of the promise when this
289
+ * result is `Ok`.
290
+ *
291
+ * Otherwise, returns `Err` containing the current error value.
292
+ *
293
+ * Uses the same strategy as {@link Result.$safePromise}, equivalent to
294
+ * calling:
295
+ *
296
+ * ```ts
297
+ * resultAsync.$andThen(() => Result.$safePromise(...))
298
+ * ```
299
+ */
300
+ $andSafePromise<U = T>(this: ResultAsync<T, E>, promise: PromiseLike<U>): ResultAsync<U, E | Error>;
301
+ $andSafePromise<U = T, F = E>(this: ResultAsync<T, E>, promise: PromiseLike<U>, mapError: (err: unknown) => F): ResultAsync<U, E | F>;
302
+ /**
303
+ * The same as {@link Retuple.$peek|$peek}, except it:
304
+ *
305
+ * - awaits the peek function;
306
+ * - returns {@link ResultAsync}.
164
307
  */
165
- $promise(this: ResultAsync<T, E>): Promise<Result<T, E>>;
166
- }
167
- type OkTuple<T> = [err: undefined, value: T];
168
- type ErrTuple<E> = [err: E, value: undefined];
169
- type Truthy<T> = Exclude<T, false | null | undefined | 0 | 0n | "">;
170
- /**
171
- * @TODO - Result.all / Result.any
172
- */
173
- interface Retuple<T, E> {
174
- /**
175
- * @TODO
176
- */
177
- $isOk(this: Result<T, E>): this is Ok<T>;
308
+ $peek(this: ResultAsync<T, E>, f: (res: Result<T, E>) => any): ResultAsync<T, E>;
178
309
  /**
179
- * @TODO
310
+ * The same as {@link Retuple.$tap|$tap}, except it:
311
+ *
312
+ * - awaits the tap function;
313
+ * - returns {@link ResultAsync}.
180
314
  */
181
- $isOkAnd<U extends T = T>(this: Result<T, E>, f: ((val: T) => val is U) | ((val: T) => boolean)): this is Ok<U>;
315
+ $tap(this: ResultAsync<T, E>, f: (val: T) => any): ResultAsync<T, E>;
182
316
  /**
183
- * @TODO
317
+ * The same as {@link Retuple.$tapErr|$tapErr}, except it:
318
+ *
319
+ * - awaits the tap error function;
320
+ * - returns {@link ResultAsync}.
184
321
  */
185
- $isErr(this: Result<T, E>): this is Err<E>;
322
+ $tapErr(this: ResultAsync<T, E>, f: (err: E) => any): ResultAsync<T, E>;
186
323
  /**
187
- * @TODO
324
+ * The same as {@link Retuple.$promise|$promise}.
188
325
  */
189
- $isErrAnd<F extends E = E>(this: Result<T, E>, f: ((err: E) => err is F) | ((err: E) => boolean)): this is Err<F>;
326
+ $promise(this: ResultAsync<T, E>): Promise<Result<T, E>>;
190
327
  /**
191
- * @TODO
328
+ * The same as {@link Retuple.$iter|$iter}, except it returns a `Promise`.
192
329
  */
193
- $value(this: Result<T, E>): T | E;
194
- /**
195
- * @TODO
330
+ $iter<U>(this: ResultAsync<Iterable<U>, E>): Promise<IterableIterator<U, undefined, unknown>>;
331
+ }
332
+ /**
333
+ * ## ResultRetry
334
+ */
335
+ declare class ResultRetry<T, E> extends ResultAsync<T, E> implements PromiseLike<Result<T, E>> {
336
+ #private;
337
+ private static MAX_TIMEOUT;
338
+ private static MAX_RETRY;
339
+ private static zero;
340
+ private static delay;
341
+ private static integer;
342
+ constructor(f: () => ResultLikeAwaitable<T, E>);
343
+ then<U = Result<T, E>, F = never>(this: ResultRetry<T, E>, onfulfilled?: ((value: Result<T, E>) => U | PromiseLike<U>) | null | undefined, onrejected?: ((reason: any) => F | PromiseLike<F>) | null | undefined): PromiseLike<U | F>;
344
+ /**
345
+ * Sets the maximum number of times the retry function can be executed,
346
+ * mutating this `ResultRetry` instance.
347
+ *
348
+ * **The default value is 1 - meaning that unless set, no retries will be
349
+ * attempted.**
350
+ *
351
+ * The retry function can be called up to the maximum number of times until
352
+ * it returns `Ok`. If it never returns `Ok`, the most recent `Err` is
353
+ * returned.
354
+ *
355
+ * This function accepts a positive integer between 1 and 100:
356
+ *
357
+ * - Integers outside of this range are clamped to the nearest valid value;
358
+ * - Any other value (NaN, Infinity, fractions, strings) are treated as 1.
359
+ *
360
+ * @example
361
+ *
362
+ * ```ts
363
+ * // Retry someResultFn up to 3 times until Ok is returned:
364
+ * const result = await Result.$retry(someResultFn).$times(3);
365
+ * ```
366
+ */
367
+ $times<N extends number>(this: ResultRetry<T, E>, times: NonZero<N> & NonNegativeOrDecimal<N>): ResultRetry<T, E>;
368
+ /**
369
+ * Sets the delay between each retry attempt, mutating this `ResultRetry`
370
+ * instance.
371
+ *
372
+ * - Provide a number of milliseconds to introduce a static delay between
373
+ * attempts;
374
+ * - Provide a function to compute the delay dynamically for each attempt;
375
+ * - If the maximum number of retries is 1, this setting as no effect.
376
+ *
377
+ * **The default value is 0 - meaning that unless set, there will be no delay
378
+ * between attempts.**
379
+ *
380
+ * This function accepts an integer between 0 and 3600000:
381
+ *
382
+ * - Integers outside of this range are clamped to the nearest valid value;
383
+ * - Any other value (NaN, Infinity, fractions, strings) are treated as 0.
384
+ *
385
+ * @example
386
+ *
387
+ * ```ts
388
+ * // Retry someResultFn up to 3 times until Ok is returned,
389
+ * // with a 1 second delay between each invocation:
390
+ * const result = await Result.$retry(someResultFn).$times(3).$delay(1000);
391
+ * ```
392
+ */
393
+ $delay<N extends number>(this: ResultRetry<T, E>, f: (attempt: number) => NonNegativeOrDecimal<N>): ResultRetry<T, E>;
394
+ $delay<N extends number>(this: ResultRetry<T, E>, ms: NonNegativeOrDecimal<N>): ResultRetry<T, E>;
395
+ /**
396
+ * Sets a handler to be called when an attempt returns `Err`, mutating this
397
+ * `ResultRetry` instance. The handler can be used to capture information
398
+ * about each failure, and to abort early and prevent further retries.
399
+ *
400
+ * The handler function is called with `ResultRetryHandleState`, containing:
401
+ *
402
+ * - **error** - The error value from the last failed attempt;
403
+ * - **attempt** - The attempt number;
404
+ * - **abort** - A function which when called, prevents further retries.
405
+ *
406
+ * @example
407
+ *
408
+ * ```ts
409
+ * // Retry someResultFn up to 3 times until Ok is returned, logging each
410
+ * // attempt and aborting early if the error code is "UNAUTHORIZED".
411
+ * const result = await Result.$retry(someResultFn)
412
+ * .$times(3)
413
+ * .$handle(({ error, attempt, abort }) => {
414
+ * console.info(`Attempt ${attempt} failed: ${error}`);
415
+ * if (error === "UNAUTHORIZED") {
416
+ * abort();
417
+ * }
418
+ * });
419
+ * ```
420
+ */
421
+ $handle(f: (controller: ResultRetryController<E>) => void): ResultRetry<T, E>;
422
+ private drain;
423
+ }
424
+ interface Retuple<T, E> extends ResultLike<T, E> {
425
+ /**
426
+ * Returns true when this result is `Ok`. Acts as a type guard.
427
+ *
428
+ * @example
429
+ *
430
+ * ```ts
431
+ * const result = Ok("test");
432
+ * assert.equal(result.$isOk(), true);
433
+ * ```
434
+ *
435
+ * @example
436
+ *
437
+ * ```ts
438
+ * const result = Err("test");
439
+ * assert.equal(result.$isOk(), false);
440
+ * ```
441
+ *
442
+ * @example
443
+ *
444
+ * ```ts
445
+ * const result: Result<string, Error> = someResultFn();
446
+ *
447
+ * if (result.$isOk()) {
448
+ * result satisfies Result<string, never>;
449
+ * }
450
+ * ```
451
+ */
452
+ $isOk(this: Result<T, E>): this is Result<T, never>;
453
+ /**
454
+ * Returns true when this result is `Ok`, and when the predicate/condition
455
+ * function returns true. Acts as a type guard.
456
+ *
457
+ * @example
458
+ *
459
+ * ```ts
460
+ * const result = Ok("test");
461
+ * assert.equal(result.$isOkAnd((val) => val === "test"), true);
462
+ * ```
463
+ *
464
+ * @example
465
+ *
466
+ * ```ts
467
+ * const result = Ok<string>("test");
468
+ * assert.equal(result.$isOkAnd((val) => val !== "test"), false);
469
+ * ```
470
+ *
471
+ * @example
472
+ *
473
+ * ```ts
474
+ * const result = Err("test");
475
+ * assert.equal(result.$isOkAnd((err) => err === "test"), false);
476
+ * ```
477
+ *
478
+ * @example
479
+ *
480
+ * ```ts
481
+ * const result: Result<string | number, Error> = someResultFn();
482
+ *
483
+ * if (result.$isOkAnd((val): val is number => typeof val === "number")) {
484
+ * result satisfies Result<number, never>;
485
+ * }
486
+ * ```
487
+ */
488
+ $isOkAnd<U extends T = T>(this: Result<T, E>, predicate: (val: T) => val is U): this is Result<U, never>;
489
+ $isOkAnd(this: Result<T, E>, predicate: (val: T) => unknown): this is Result<T, never>;
490
+ /**
491
+ * Returns true when this result is `Err`. Acts as a type guard.
492
+ *
493
+ * @example
494
+ *
495
+ * ```ts
496
+ * const result = Err("test");
497
+ * assert.equal(result.$isErr(), true);
498
+ * ```
499
+ *
500
+ * @example
501
+ *
502
+ * ```ts
503
+ * const result = Ok("test");
504
+ * assert.equal(result.$isErr(), false);
505
+ * ```
506
+ *
507
+ * @example
508
+ *
509
+ * ```ts
510
+ * const result: Result<string, Error> = someResultFn();
511
+ *
512
+ * if (result.$isErr()) {
513
+ * result satisfies Result<never, Error>;
514
+ * }
515
+ * ```
516
+ */
517
+ $isErr(this: Result<T, E>): this is Result<never, E>;
518
+ /**
519
+ * Returns true when this result is `Err`, and when the predicate/condition
520
+ * function returns true. Acts as a type guard.
521
+ *
522
+ * @example
523
+ *
524
+ * ```ts
525
+ * const result = Err("test");
526
+ * assert.equal(result.$isErrAnd((err) => err === "test"), true);
527
+ * ```
528
+ *
529
+ * @example
530
+ *
531
+ * ```ts
532
+ * const result = Err<string>("test");
533
+ * assert.equal(result.$isErrAnd((err) => err !== "test"), false);
534
+ * ```
535
+ *
536
+ * @example
537
+ *
538
+ * ```ts
539
+ * const result = Ok("test");
540
+ * assert.equal(result.$isErrAnd((val) => val === "test"), false);
541
+ * ```
542
+ *
543
+ * @example
544
+ *
545
+ * ```ts
546
+ * const result: Result<string, Error | number> = someResultFn();
547
+ *
548
+ * if (result.$isErrAnd((err): err is number => typeof err === "number")) {
549
+ * result satisfies Result<never, number>;
550
+ * }
551
+ * ```
552
+ */
553
+ $isErrAnd<F extends E = E>(this: Result<T, E>, prediacte: (val: E) => val is F): this is Result<never, F>;
554
+ $isErrAnd(this: Result<T, E>, predicate: (val: E) => unknown): this is Result<never, E>;
555
+ /**
556
+ * Returns the ok value when this result is `Ok`.
557
+ *
558
+ * Otherwise, the error value is thrown.
559
+ *
560
+ * This method should only be called when the `E` type extends `Error`. This
561
+ * is enforced with a type constraint. If the error value is not an instance
562
+ * of Error, `RetupleExpectFailed` is thrown. Use
563
+ * {@link Retuple.$unwrap|$unwrap} When the `E` type does not extend Error.
564
+ *
565
+ * @example
566
+ *
567
+ * ```ts
568
+ * const result = Ok("test");
569
+ * assert.equal(result.$expect(), "test");
570
+ * ```
571
+ *
572
+ * @example
573
+ *
574
+ * ```ts
575
+ * const error = new Error("test");
576
+ * const result = Err(error);
577
+ *
578
+ * try {
579
+ * const value = result.$expect(); // throws
580
+ * } catch (e) {
581
+ * assert.equal(e, error);
582
+ * }
583
+ * ```
584
+ *
585
+ * @example
586
+ *
587
+ * ```ts
588
+ * const result = Err("test");
589
+ *
590
+ * try {
591
+ * // This is a type error - the E type does not extend Error
592
+ * const value = result.$expect(); // throws
593
+ * } catch (e) {
594
+ * assert(e instanceof RetupleExpectFailed && e.value === "test");
595
+ * }
596
+ * ```
196
597
  */
197
598
  $expect(this: Result<T, Error>): T;
198
599
  /**
199
- * @TODO
600
+ * Returns the ok value when this result is `Ok`.
601
+ *
602
+ * Otherwise, `RetupleUnwrapFailed` is thrown. A custom error message can be
603
+ * provided.
604
+ *
605
+ * @example
606
+ *
607
+ * ```ts
608
+ * const result = Ok("test");
609
+ * assert.equal(result.$unwrap(), "test");
610
+ * ```
611
+ *
612
+ * @example
613
+ *
614
+ * ```ts
615
+ * const result = Err("test");
616
+ *
617
+ * try {
618
+ * const value = result.$unwrap(); // throws
619
+ * } catch (e) {
620
+ * assert(e instanceof RetupleUnwrapFailed && e.value === "test");
621
+ * }
622
+ * ```
623
+ *
624
+ * @example
625
+ *
626
+ * ```ts
627
+ * const error = new Error("test");
628
+ * const result = Err(error);
629
+ *
630
+ * try {
631
+ * const value = result.$unwrap("error-message"); // throws
632
+ * } catch (e) {
633
+ * assert(
634
+ * e instanceof RetupleUnwrapFailed &&
635
+ * e.message === "error-message" &&
636
+ * e.value === error &&
637
+ * e.cause === error, // set when error value was an instance of `Error`
638
+ * );
639
+ * }
640
+ * ```
200
641
  */
201
642
  $unwrap(this: Result<T, E>, msg?: string): T;
202
643
  /**
203
- * @TODO
644
+ * Returns the error value when this result is `Err`.
645
+ *
646
+ * Otherwise, `RetupleUnwrapErrFailed` is thrown. A custom error message can
647
+ * be provided.
648
+ *
649
+ * @example
650
+ *
651
+ * ```ts
652
+ * const result = Err("test");
653
+ * assert.equal(result.$unwrapErr(), "test");
654
+ * ```
655
+ *
656
+ * @example
657
+ *
658
+ * ```ts
659
+ * const result = Ok("test");
660
+ *
661
+ * try {
662
+ * const value = result.$unwrapErr(); // throws
663
+ * } catch (e) {
664
+ * assert(e instanceof RetupleUnwrapErrFailed && e.value === "test");
665
+ * }
666
+ * ```
667
+ *
668
+ * @example
669
+ *
670
+ * ```ts
671
+ * const result = Ok("test");
672
+ *
673
+ * try {
674
+ * const value = result.$unwrapErr("error-message"); // throws
675
+ * } catch (e) {
676
+ * assert(
677
+ * e instanceof RetupleUnwrapErrFailed &&
678
+ * e.message === "error-message" &&
679
+ * e.value === "test",
680
+ * );
681
+ * }
682
+ * ```
204
683
  */
205
684
  $unwrapErr(this: Result<T, E>, msg?: string): E;
206
685
  /**
207
- * @TODO
208
- */
209
- $unwrapOr<U = T>(this: Result<T, E>, def: U): T | U;
210
- /**
211
- * @TODO
686
+ * Returns the ok value when this result is `Ok`.
687
+ *
688
+ * Otherwise, returns the default value.
689
+ *
690
+ * @example
691
+ *
692
+ * ```ts
693
+ * const result = Ok("test");
694
+ * assert.equal(result.$unwrapOr("default"), "test");
695
+ * ```
696
+ *
697
+ * @example
698
+ *
699
+ * ```ts
700
+ * const result = Err("test");
701
+ * assert.equal(result.$unwrapOr("default"), "default");
702
+ * ```
703
+ */
704
+ $unwrapOr<const U = T>(this: Result<T, E>, def: U): T | U;
705
+ /**
706
+ * Returns the ok value when this result is `Ok`.
707
+ *
708
+ * Otherwise, returns the value returned by the default function.
709
+ *
710
+ * @example
711
+ *
712
+ * ```ts
713
+ * const result = Ok("test");
714
+ * assert.equal(result.$unwrapOrElse(() => "default"), "test");
715
+ * ```
716
+ *
717
+ * @example
718
+ *
719
+ * ```ts
720
+ * const result = Err("test");
721
+ * assert.equal(result.$unwrapOrElse(() => "default"), "default");
722
+ * ```
212
723
  */
213
724
  $unwrapOrElse<U = T>(this: Result<T, E>, f: () => U): T | U;
214
725
  /**
215
- * @TODO
726
+ * Performs an assertion when this result is `Ok`:
727
+ *
728
+ * - returning `Ok` containing the current ok value when it is truthy, and
729
+ * when no predicate/condition function is provided. Narrows the `T` type
730
+ * to include only truthy values;
731
+ * - returning `Ok` containing the current ok value when a
732
+ * predicate/condition function is provided and it returns a truthy value.
733
+ * Narrows the `T` type to the predicate type (if any);
734
+ * - returning the default result when no predicate/condition function is
735
+ * provided and the current ok value is falsey;
736
+ * - returning the default result when a predicate/condition function is
737
+ * provided and it returns a falsey value.
738
+ *
739
+ * Otherwise returns `Err` containing the current error value.
740
+ *
741
+ * @example
742
+ *
743
+ * ```ts
744
+ * const result: Result<string | null, string> = Ok("test");
745
+ * const asserted = result.$andAssertOr(Ok("ok-default"));
746
+ *
747
+ * asserted satisfies Result<string, string>;
748
+ * assert.equal(asserted.$unwrap(), "test");
749
+ * ```
750
+ *
751
+ * @example
752
+ *
753
+ * ```ts
754
+ * const result: Result<string | null, string> = Ok("test");
755
+ * const asserted = result.$andAssertOr(
756
+ * Err("err-default"),
757
+ * (val): val is "test" => val === "test",
758
+ * );
759
+ *
760
+ * asserted satisfies Result<"test", string>;
761
+ * assert.equal(asserted.$unwrap(), "test");
762
+ * ```
763
+ *
764
+ * @example
765
+ *
766
+ * ```ts
767
+ * const result: Result<string | null, string> = Ok(null);
768
+ * const asserted = result.$andAssertOr(Ok("ok-default"));
769
+ *
770
+ * asserted satisfies Result<string, string>;
771
+ * assert.equal(asserted.$unwrap(), "ok-default");
772
+ * ```
773
+ *
774
+ * @example
775
+ *
776
+ * ```ts
777
+ * const result: Result<string | null, string> = Ok("value");
778
+ * const asserted = result.$andAssertOr(
779
+ * Err("err-default"),
780
+ * (val): val is "test" => val === "test",
781
+ * );
782
+ *
783
+ * asserted satisfies Result<"test", string>;
784
+ * assert.equal(asserted.$unwrapErr(), "err-default");
785
+ * ```
786
+ *
787
+ * @example
788
+ *
789
+ * ```ts
790
+ * const result: Result<string | null, string> = Err("test");
791
+ * const asserted = result.$andAssertOr(
792
+ * Err("err-default"),
793
+ * (val): val is "test" => val === "test",
794
+ * );
795
+ *
796
+ * asserted satisfies Result<"test", string>;
797
+ * assert.equal(asserted.$unwrapErr(), "test");
798
+ * ```
799
+ */
800
+ $andAssertOr<U = T, F = E>(this: Result<T, E>, def: ResultLike<U, F>): Result<Truthy<T> | U, E | F>;
801
+ $andAssertOr<U = T, F = E, A extends T = T>(this: Result<T, E>, def: ResultLike<U, F>, predicate: (val: T) => val is A): Result<U | A, E | F>;
802
+ $andAssertOr<U = T, F = E>(this: Result<T, E>, def: ResultLike<U, F>, condition: (val: T) => unknown): Result<T | U, E | F>;
803
+ /**
804
+ * Performs an assertion when this result is `Ok`:
805
+ *
806
+ * - returning `Ok` containing the current ok value when it is truthy, and
807
+ * when no predicate/condition function is provided. Narrows the `T` type
808
+ * to include only truthy values;
809
+ * - returning `Ok` containing the current ok value when a
810
+ * predicate/condition function is provided and it returns a truthy value.
811
+ * Narrows the `T` type to the predicate type (if any);
812
+ * - returning the result returned by the default function when no
813
+ * predicate/condition function is provided and the current ok value is
814
+ * falsey;
815
+ * - returning the result returned by the default function when a
816
+ * predicate/condition function is provided and it returns a falsey value.
817
+ *
818
+ * Otherwise returns `Err` containing the current error value.
819
+ *
820
+ * @example
821
+ *
822
+ * ```ts
823
+ * const result: Result<string | null, string> = Ok("test");
824
+ * const asserted = result.$andAssertOrElse(
825
+ * (val) => Ok(`ok-default:${val}`),
826
+ * );
827
+ *
828
+ * asserted satisfies Result<string, string>;
829
+ * assert.equal(asserted.$unwrap(), "test");
830
+ * ```
831
+ *
832
+ * @example
833
+ *
834
+ * ```ts
835
+ * const result: Result<string | null, string> = Ok("test");
836
+ * const asserted = result.$andAssertOrElse(
837
+ * (val) => Err(`err-default:${val}`),
838
+ * (val): val is "test" => val === "test",
839
+ * );
840
+ *
841
+ * asserted satisfies Result<"test", string>;
842
+ * assert.equal(asserted.$unwrap(), "test");
843
+ * ```
844
+ *
845
+ * @example
846
+ *
847
+ * ```ts
848
+ * const result: Result<string | null, string> = Ok(null);
849
+ * const asserted = result.$andAssertOrElse(
850
+ * (val) => Ok(`ok-default:${val}`),
851
+ * );
852
+ *
853
+ * asserted satisfies Result<string, string>;
854
+ * assert.equal(asserted.$unwrap(), "ok-default:null");
855
+ * ```
856
+ *
857
+ * @example
858
+ *
859
+ * ```ts
860
+ * const result: Result<string | null, string> = Ok("value");
861
+ * const asserted = result.$andAssertOrElse(
862
+ * (val) => Err(`err-default:${val}`),
863
+ * (val): val is "test" => val === "test",
864
+ * );
865
+ *
866
+ * asserted satisfies Result<"test", string>;
867
+ * assert.equal(asserted.$unwrapErr(), "err-default:value");
868
+ * ```
869
+ *
870
+ * @example
871
+ *
872
+ * ```ts
873
+ * const result: Result<string | null, string> = Err("test");
874
+ * const asserted = result.$andAssertOrElse(
875
+ * (val) => Err(`err-default:${val}`),
876
+ * (val): val is "test" => val === "test",
877
+ * );
878
+ *
879
+ * asserted satisfies Result<"test", string>;
880
+ * assert.equal(asserted.$unwrapErr(), "test");
881
+ * ```
882
+ */
883
+ $andAssertOrElse<U = T, F = E>(this: Result<T, E>, def: (val: T) => ResultLike<U, F>): Result<Truthy<T> | U, E | F>;
884
+ $andAssertOrElse<U = T, F = E, A extends T = T>(this: Result<T, E>, def: (val: T) => ResultLike<U, F>, predicate: (val: T) => val is A): Result<U | A, E | F>;
885
+ $andAssertOrElse<U = T, F = E>(this: Result<T, E>, def: (val: T) => ResultLike<U, F>, condition: (val: T) => unknown): Result<T | U, E | F>;
886
+ /**
887
+ * Returns `Ok` containing the return value of the map function when this
888
+ * result is `Ok`.
889
+ *
890
+ * Otherwise, returns `Err` containing the current error value.
891
+ *
892
+ * @example
893
+ *
894
+ * ```ts
895
+ * const result = Ok("test");
896
+ * assert.equal(
897
+ * result.$map((val) => `map:${val}`).$unwrap(),
898
+ * "map:test",
899
+ * );
900
+ * ```
901
+ *
902
+ * @example
903
+ *
904
+ * ```ts
905
+ * const result: Result<string, string> = Err("test");
906
+ * assert.equal(
907
+ * result.$map((val) => `map:${val}`).$unwrapErr(),
908
+ * "test",
909
+ * );
910
+ * ```
216
911
  */
217
912
  $map<U>(this: Result<T, E>, f: (value: T) => U): Result<U, E>;
218
913
  /**
219
- * @TODO
220
- */
221
- $mapErr<F>(this: Result<T, E>, f: (err: E) => F): Result<T, F>;
222
- /**
223
- * @TODO
224
- */
225
- $mapOr<U>(this: Result<T, E>, def: U, f: (val: T) => U): Result<U, E>;
226
- /**
227
- * @TODO
228
- */
229
- $mapOrElse<U>(this: Result<T, E>, def: (err: E) => U, f: (val: T) => U): Result<U, E>;
230
- /**
231
- * @TODO
232
- */
233
- $or<U = T, F = E>(this: Result<T, E>, or: Result<U, F>): Result<T | U, E | F>;
234
- /**
235
- * @TODO
236
- */
237
- $orElse<U = never, F = never>(this: Result<T, E>, f: (err: E) => Result<U, F>): Result<T | U, E | F>;
238
- /**
239
- * @TODO
240
- */
241
- $orSafe<U = T>(this: Result<T, E>, f: (err: E) => U): Result<T | U, E | Error>;
242
- $orSafe<U = T, F = E>(this: Result<T, E>, f: (err: E) => U, mapError: (err: unknown) => F): Result<T | U, E | F>;
243
- $orSafe<U = T, F = Error>(this: Result<T, E>, f: (err: E) => U, mapError: (err: unknown) => F): Result<T | U, E | F>;
244
- /**
245
- * @TODO
246
- */
247
- $and<U = T, F = E>(this: Result<T, E>, and: Result<U, F>): Result<U, E | F>;
248
- /**
249
- * @TODO
250
- */
251
- $andThen<U = never, F = never>(this: Result<T, E>, f: (val: T) => Result<U, F>): Result<U, E | F>;
252
- /**
253
- * @TODO
254
- */
255
- $andThrough<F = never>(this: Result<T, E>, f: (val: T) => Result<any, F>): Result<T, E | F>;
256
- /**
257
- * @TODO
258
- */
259
- $andSafe<U = T>(this: Result<T, E>, f: (val: T) => U): Result<T | U, E | Error>;
260
- $andSafe<U = T, F = E>(this: Result<T, E>, f: (val: T) => U, mapError: (err: unknown) => F): Result<T | U, E | F>;
261
- $andSafe<U, F = Error>(this: Result<T, E>, f: (val: T) => U, mapError: (err: unknown) => F): Result<T | U, E | F>;
262
- /**
263
- * @TODO
914
+ * Returns `Err` containing the return value of the map function when this
915
+ * result is `Err`.
916
+ *
917
+ * Otherwise, returns `Ok` containing the current ok value.
918
+ *
919
+ * @example
920
+ *
921
+ * ```ts
922
+ * const result = Err("test");
923
+ * assert.equal(
924
+ * result.$mapErr((err) => `map-err:${err}`).$unwrapErr(),
925
+ * "map-err:test",
926
+ * );
927
+ * ```
928
+ *
929
+ * @example
930
+ *
931
+ * ```ts
932
+ * const result: Result<string, string> = Ok("test");
933
+ * assert.equal(
934
+ * result.$mapErr((err) => `map-err:${err}`).$unwrap(),
935
+ * "test",
936
+ * );
937
+ * ```
938
+ */
939
+ $mapErr<F = E>(this: Result<T, E>, f: (err: E) => F): Result<T, F>;
940
+ /**
941
+ * Returns `Ok` containing the return value of the map function when this
942
+ * result is `Ok`.
943
+ *
944
+ * Otherwise, returns `Ok` containing the default value.
945
+ *
946
+ * @example
947
+ *
948
+ * ```ts
949
+ * const result: Result<string, string> = Ok("test");
950
+ * assert.equal(
951
+ * result.$mapOr("default", (val) => `map:${val}`).$unwrap(),
952
+ * "map:test",
953
+ * );
954
+ * ```
955
+ *
956
+ * @example
957
+ *
958
+ * ```ts
959
+ * const result: Result<string, string> = Err("test");
960
+ * assert.equal(
961
+ * result.$mapOr("default", (val) => `map:${val}`).$unwrap(),
962
+ * "default",
963
+ * );
964
+ * ```
965
+ */
966
+ $mapOr<U, V = U>(this: Result<T, E>, def: U, f: (val: T) => V): Result<U | V, never>;
967
+ /**
968
+ * Returns `Ok` containing the return value of the map function when this
969
+ * result is `Ok`.
970
+ *
971
+ * Otherwise, returns `Ok` containing the return value of the default
972
+ * function.
973
+ *
974
+ * @example
975
+ *
976
+ * ```ts
977
+ * const result: Result<string, string> = Ok("test");
978
+ * assert.equal(
979
+ * result.$mapOrElse(
980
+ * (err) => `default:${err}`,
981
+ * (val) => `map:${val}`,
982
+ * ).$unwrap(),
983
+ * "map:test",
984
+ * );
985
+ * ```
986
+ *
987
+ * @example
988
+ *
989
+ * ```ts
990
+ * const result: Result<string, string> = Err("test");
991
+ * assert.equal(
992
+ * result.$mapOrElse(
993
+ * (err) => `default:${err}`,
994
+ * (val) => `map:${val}`,
995
+ * ).$unwrap(),
996
+ * "default:test",
997
+ * );
998
+ * ```
999
+ */
1000
+ $mapOrElse<U, V = U>(this: Result<T, E>, def: (err: E) => U, f: (val: T) => V): Result<U | V, never>;
1001
+ /**
1002
+ * Returns the or result, when this result is `Err`.
1003
+ *
1004
+ * Otherwise, returns `Ok` containing the current ok value.
1005
+ *
1006
+ * @example
1007
+ *
1008
+ * ```ts
1009
+ * const result = Err("test");
1010
+ * assert.equal(
1011
+ * result.$or(Ok("or-ok")).$unwrap(),
1012
+ * "or-ok",
1013
+ * );
1014
+ * ```
1015
+ *
1016
+ * @example
1017
+ *
1018
+ * ```ts
1019
+ * const result = Err("test");
1020
+ * assert.equal(
1021
+ * result.$or(Err("or-err")).$unwrapErr(),
1022
+ * "or-err",
1023
+ * );
1024
+ * ```
1025
+ *
1026
+ * @example
1027
+ *
1028
+ * ```ts
1029
+ * const result = Ok("test");
1030
+ * assert.equal(
1031
+ * result.$or(Ok("or-ok")).$unwrap(),
1032
+ * "test",
1033
+ * );
1034
+ * ```
1035
+ */
1036
+ $or<U = T, F = E>(this: Result<T, E>, or: ResultLike<U, F>): Result<T | U, F>;
1037
+ /**
1038
+ * Shorthand for `result.$async().$or(...)`
1039
+ */
1040
+ $orAsync<U = T, F = E>(this: Result<T, E>, or: ResultLikeAwaitable<U, F>): ResultAsync<T | U, F>;
1041
+ /**
1042
+ * Returns the result returned by the or function, when this result is `Err`.
1043
+ *
1044
+ * Otherwise, returns `Ok` containing the current ok value.
1045
+ *
1046
+ * @example
1047
+ *
1048
+ * ```ts
1049
+ * const result = Err("test");
1050
+ * assert.equal(
1051
+ * result.$orElse((err) => Ok(`or-ok:${err}`)).$unwrap(),
1052
+ * "or-ok:test",
1053
+ * );
1054
+ * ```
1055
+ *
1056
+ * @example
1057
+ *
1058
+ * ```ts
1059
+ * const result = Err("test");
1060
+ * assert.equal(
1061
+ * result.$orElse((err) => Err(`or-err:${err}`)).$unwrapErr(),
1062
+ * "or-err:test",
1063
+ * );
1064
+ * ```
1065
+ *
1066
+ * @example
1067
+ *
1068
+ * ```ts
1069
+ * const result: Result<string, string> = Ok("test");
1070
+ * assert.equal(
1071
+ * result.$orElse((err) => Ok(`or-ok:${err}`)).$unwrap(),
1072
+ * "test",
1073
+ * );
1074
+ * ```
1075
+ */
1076
+ $orElse<U = T, F = E>(this: Result<T, E>, f: (err: E) => ResultLike<U, F>): Result<T | U, F>;
1077
+ /**
1078
+ * Shorthand for `result.$async().$orElse(...)`
1079
+ */
1080
+ $orElseAsync<U = T, F = E>(this: Result<T, E>, f: (err: E) => ResultLikeAwaitable<U, F>): ResultAsync<T | U, F>;
1081
+ /**
1082
+ * Returns a {@link Result} based on the outcome of the safe function when
1083
+ * this result is `Err`.
1084
+ *
1085
+ * Otherwise, returns `Ok` containing the current ok value.
1086
+ *
1087
+ * Uses the same strategy as {@link Result.$safe}, equivalent to calling
1088
+ * `result.$or(Result.$safe(...))`.
1089
+ */
1090
+ $orSafe<U = T>(this: Result<T, E>, f: (err: E) => U): Result<T | U, Error>;
1091
+ $orSafe<U = T, F = E>(this: Result<T, E>, f: (err: E) => U, mapError: (err: unknown) => F): Result<T | U, F>;
1092
+ /**
1093
+ * Shorthand for `result.$async().$orSafe(...)`
1094
+ */
1095
+ $orSafeAsync<U = T>(this: Result<T, E>, f: (err: E) => U | PromiseLike<U>): ResultAsync<T | U, Error>;
1096
+ $orSafeAsync<U = T, F = E>(this: Result<T, E>, f: (err: E) => U | PromiseLike<U>, mapError: (err: unknown) => F): ResultAsync<T | U, F>;
1097
+ /**
1098
+ * Shorthand for `result.$async().$orSafePromise(...)`
1099
+ */
1100
+ $orSafePromise<U = T>(this: Result<T, E>, promise: PromiseLike<U>): ResultAsync<T | U, Error>;
1101
+ $orSafePromise<U = T, F = E>(this: Result<T, E>, promise: PromiseLike<U>, mapError: (err: unknown) => F): ResultAsync<T | U, F>;
1102
+ /**
1103
+ * Returns the and result, when this result is `Ok`.
1104
+ *
1105
+ * Otherwise, returns `Err` containing the current error value.
1106
+ *
1107
+ * @example
1108
+ *
1109
+ * ```ts
1110
+ * const result = Ok("test");
1111
+ * assert.equal(
1112
+ * result.$and(Ok("and-ok")).$unwrap(),
1113
+ * "and-ok",
1114
+ * );
1115
+ * ```
1116
+ *
1117
+ * @example
1118
+ *
1119
+ * ```ts
1120
+ * const result = Ok("test");
1121
+ * assert.equal(
1122
+ * result.$and(Err("and-err")).$unwrapErr(),
1123
+ * "and-err",
1124
+ * );
1125
+ * ```
1126
+ *
1127
+ * @example
1128
+ *
1129
+ * ```ts
1130
+ * const result = Err("test");
1131
+ * assert.equal(
1132
+ * result.$and(Ok("and-ok")).$unwrapErr(),
1133
+ * "test",
1134
+ * );
1135
+ * ```
1136
+ */
1137
+ $and<U = T, F = E>(this: Result<T, E>, and: ResultLike<U, F>): Result<U, E | F>;
1138
+ /**
1139
+ * Shorthand for `result.$async().$and(...)`
1140
+ */
1141
+ $andAsync<U = T, F = E>(this: Result<T, E>, and: ResultLikeAwaitable<U, F>): ResultAsync<U, E | F>;
1142
+ /**
1143
+ * Returns the and result, when this result is `Ok`.
1144
+ *
1145
+ * Otherwise, returns `Err` containing the current error value.
1146
+ *
1147
+ * @example
1148
+ *
1149
+ * ```ts
1150
+ * const result = Ok("test");
1151
+ * assert.equal(
1152
+ * result.$and((val) => Ok(`and-ok:${val}`)).$unwrap(),
1153
+ * "and-ok:test",
1154
+ * );
1155
+ * ```
1156
+ *
1157
+ * @example
1158
+ *
1159
+ * ```ts
1160
+ * const result = Ok("test");
1161
+ * assert.equal(
1162
+ * result.$and((val) => Err(`and-err:${val}`)).$unwrapErr(),
1163
+ * "and-err:test",
1164
+ * );
1165
+ * ```
1166
+ *
1167
+ * @example
1168
+ *
1169
+ * ```ts
1170
+ * const result: Result<string, string> = Err("test");
1171
+ * assert.equal(
1172
+ * result.$and((val) => Ok(`and-ok:${val}`)).$unwrapErr(),
1173
+ * "test",
1174
+ * );
1175
+ * ```
1176
+ */
1177
+ $andThen<U = T, F = E>(this: Result<T, E>, f: (val: T) => ResultLike<U, F>): Result<U, E | F>;
1178
+ /**
1179
+ * Shorthand for `result.$async().$andThen(...)`
1180
+ */
1181
+ $andThenAsync<U = T, F = E>(this: Result<T, E>, f: (val: T) => ResultLikeAwaitable<U, F>): ResultAsync<U, E | F>;
1182
+ /**
1183
+ * Calls the through function when this result is `Ok` and returns:
1184
+ *
1185
+ * - `Ok` containing the original ok value when the through function
1186
+ * returns `Ok`;
1187
+ * - the `Err` returned by the through function when it returns `Err`.
1188
+ *
1189
+ * Otherwise, returns `Err` containing the current error value.
1190
+ *
1191
+ * @example
1192
+ *
1193
+ * ```ts
1194
+ * const result = Ok("test");
1195
+ * assert.equal(
1196
+ * result.$andThrough((val) => Ok(`ok-through:${val}`)).$unwrap(),
1197
+ * "test",
1198
+ * );
1199
+ * ```
1200
+ *
1201
+ * @example
1202
+ *
1203
+ * ```ts
1204
+ * const result = Ok("test");
1205
+ * assert.equal(
1206
+ * result.$andThrough((val) => Err(`err-through:${val}`)).$unwrapErr(),
1207
+ * "err-through:test",
1208
+ * );
1209
+ * ```
1210
+ *
1211
+ * @example
1212
+ *
1213
+ * ```ts
1214
+ * const result: Result<string, string> = Err("test");
1215
+ * assert.equal(
1216
+ * result.$andThrough((val) => Ok(`ok-through:${val}`)).$unwrapErr(),
1217
+ * "test",
1218
+ * );
1219
+ * ```
1220
+ */
1221
+ $andThrough<F = E>(this: Result<T, E>, f: (val: T) => ResultLike<any, F>): Result<T, E | F>;
1222
+ /**
1223
+ * Shorthand for `result.$async().$andThrough(...)`
1224
+ */
1225
+ $andThroughAsync<F = E>(this: Result<T, E>, f: (val: T) => ResultLikeAwaitable<any, F>): ResultAsync<T, E | F>;
1226
+ /**
1227
+ * Returns a result based on the outcome of the safe function when this
1228
+ * result is `Ok`.
1229
+ *
1230
+ * Otherwise, returns `Err` containing the current error value.
1231
+ *
1232
+ * Uses the same strategy as {@link Result.$safe}, equivalent to calling:
1233
+ *
1234
+ * ```ts
1235
+ * result.$andThen(() => Result.$safe(...))
1236
+ * ```
1237
+ */
1238
+ $andSafe<U = T>(this: Result<T, E>, f: (val: T) => U): Result<U, E | Error>;
1239
+ $andSafe<U = T, F = E>(this: Result<T, E>, f: (val: T) => U, mapError: (err: unknown) => F): Result<U, E | F>;
1240
+ /**
1241
+ * Shorthand for `result.$async().$andSafe(...)`
1242
+ */
1243
+ $andSafeAsync<U = T>(this: Result<T, E>, f: (val: T) => U | PromiseLike<U>): ResultAsync<U, E | Error>;
1244
+ $andSafeAsync<U = T, F = E>(this: Result<T, E>, f: (val: T) => U | PromiseLike<U>, mapError: (err: unknown) => F): ResultAsync<U, E | F>;
1245
+ /**
1246
+ * Shorthand for `result.$async().$andSafePromise(...)`
1247
+ */
1248
+ $andSafePromise<U = T>(this: Result<T, E>, promise: PromiseLike<U>): ResultAsync<U, E | Error>;
1249
+ $andSafePromise<U = T, F = E>(this: Result<T, E>, promise: PromiseLike<U>, mapError: (err: unknown) => F): ResultAsync<U, E | F>;
1250
+ /**
1251
+ * Calls the peek function and returns {@link Result} equivalent to this
1252
+ * result.
1253
+ *
1254
+ * @example
1255
+ *
1256
+ * ```ts
1257
+ * const result: Result<string, string> = Ok("test");
1258
+ * assert.equal(
1259
+ * result
1260
+ * .$peek((res) => {
1261
+ * const [err, value] = res;
1262
+ *
1263
+ * console.log("Err:", err); // Err: undefined
1264
+ * console.log("Value:", value); // Value: test
1265
+ * })
1266
+ * .$unwrap(),
1267
+ * "test",
1268
+ * );
1269
+ * ```
1270
+ *
1271
+ * @example
1272
+ *
1273
+ * ```ts
1274
+ * const result: Result<string, string> = Err("test");
1275
+ * assert.equal(
1276
+ * result
1277
+ * .$peek((res) => {
1278
+ * const [err, value] = res;
1279
+ *
1280
+ * console.log("Err:", err); // Err: test
1281
+ * console.log("Value:", value); // Value: undefined
1282
+ * })
1283
+ * .$unwrapErr(),
1284
+ * "test",
1285
+ * );
1286
+ * ```
264
1287
  */
265
1288
  $peek(this: Result<T, E>, f: (res: Result<T, E>) => void): Result<T, E>;
266
1289
  /**
267
- * @TODO
1290
+ * Calls the tap function when this result is `Ok`, and returns `Ok`
1291
+ * containing the current ok value.
1292
+ *
1293
+ * @example
1294
+ *
1295
+ * ```ts
1296
+ * const result = Ok("test");
1297
+ * assert.equal(
1298
+ * result
1299
+ * .$tap((val) => console.log("Value:", val)) // Value: test
1300
+ * .$unwrap(),
1301
+ * "test",
1302
+ * );
1303
+ * ```
1304
+ *
1305
+ * @example
1306
+ *
1307
+ * ```ts
1308
+ * const result: Record<string, string> = Err("test");
1309
+ * assert.equal(
1310
+ * result
1311
+ * .$tap((val) => console.log("Value:", val)) // not executed
1312
+ * .$unwrapErr(),
1313
+ * "test",
1314
+ * );
1315
+ * ```
268
1316
  */
269
1317
  $tap(this: Result<T, E>, f: (val: T) => any): Result<T, E>;
270
1318
  /**
271
- * @TODO
1319
+ * Calls the tap error function when this result is `Err`, and returns `Err`
1320
+ * containing the current error value.
1321
+ *
1322
+ * @example
1323
+ *
1324
+ * ```ts
1325
+ * const result = Err("test");
1326
+ * assert.equal(
1327
+ * result
1328
+ * .$tapErr((err) => console.log("Err:", err)) // Err: test
1329
+ * .$unwrapErr(),
1330
+ * "test",
1331
+ * );
1332
+ * ```
1333
+ *
1334
+ * @example
1335
+ *
1336
+ * ```ts
1337
+ * const result: Record<string, string> = Ok("test");
1338
+ * assert.equal(
1339
+ * result
1340
+ * .$tapErr((err) => console.log("Err:", err)) // not executed
1341
+ * .$unwrap(),
1342
+ * "test",
1343
+ * );
1344
+ * ```
272
1345
  */
273
1346
  $tapErr(this: Result<T, E>, f: (err: E) => void): Result<T, E>;
274
1347
  /**
275
- * @TODO
1348
+ * Returns the contained {@link Result} when this result is `Ok`.
1349
+ *
1350
+ * Otherwise returns `Err` containing the current error value.
1351
+ *
1352
+ * This method should only be called when the `T` type is `Result`. This
1353
+ * is enforced with a type constraint. If the ok value is not
1354
+ * a result, `RetupleFlattenFailed` is thrown.
1355
+ *
1356
+ * @example
1357
+ *
1358
+ * ```ts
1359
+ * const result = Ok(Ok("test"));
1360
+ * assert.equal(result.$flatten().$unwrap(), "test");
1361
+ * ```
1362
+ *
1363
+ * @example
1364
+ *
1365
+ * ```ts
1366
+ * const result = Ok(Err("test"));
1367
+ * assert.equal(result.$flatten().$unwrapErr(), "test");
1368
+ * ```
1369
+ *
1370
+ * @example
1371
+ *
1372
+ * ```ts
1373
+ * const result = Err("test");
1374
+ * assert.equal(result.$flatten().$unwrapErr(), "test");
1375
+ * ```
276
1376
  */
277
1377
  $flatten<U, F>(this: Result<Result<U, F>, E>): Result<U, E | F>;
278
1378
  /**
279
- * @TODO
1379
+ * Returns an equivalent {@link ResultAsync}.
1380
+ *
1381
+ * @example
1382
+ *
1383
+ * ```ts
1384
+ * const result = Ok("test").$async();
1385
+ * assert.equal(await result.$unwrap(), "test");
1386
+ * ```
1387
+ * @example
1388
+ *
1389
+ * ```ts
1390
+ * const result = Err("test").$async();
1391
+ * assert.equal(await result.$unwrapErr(), "test");
1392
+ * ```
280
1393
  */
281
1394
  $async(this: Result<T, E>): ResultAsync<T, E>;
282
1395
  /**
283
- * @TODO
1396
+ * Returns a `Promise` which resolves to this result.
1397
+ *
1398
+ * @example
1399
+ *
1400
+ * ```ts
1401
+ * const result = Ok("test").$promise();
1402
+ * assert.equal(await result, result);
1403
+ * ```
1404
+ *
1405
+ * @example
1406
+ *
1407
+ * ```ts
1408
+ * const result = Err("test").$promise();
1409
+ * assert.equal(await result, result);
1410
+ * ```
284
1411
  */
285
1412
  $promise(this: Result<T, E>): Promise<Result<T, E>>;
286
1413
  /**
287
- * Mark standard array methods as deprecated, to assist with type hinting.
288
- */
289
- /**
290
- * @deprecated
291
- */
292
- at(...args: unknown[]): unknown;
293
- /**
294
- * @deprecated
295
- */
296
- concat(...args: unknown[]): unknown;
297
- /**
298
- * @deprecated
299
- */
300
- copyWithin(...args: unknown[]): unknown;
301
- /**
302
- * @deprecated
303
- */
304
- entries(...args: unknown[]): unknown;
305
- /**
306
- * @deprecated
307
- */
308
- every(...args: unknown[]): unknown;
309
- /**
310
- * @deprecated
311
- */
312
- fill(...args: unknown[]): unknown;
313
- /**
314
- * @deprecated
315
- */
316
- filter(...args: unknown[]): unknown;
317
- /**
318
- * @deprecated
319
- */
320
- find(...args: unknown[]): unknown;
321
- /**
322
- * @deprecated
323
- */
324
- findIndex(...args: unknown[]): unknown;
325
- /**
326
- * @deprecated
327
- */
328
- flat(...args: unknown[]): unknown;
329
- /**
330
- * @deprecated
331
- */
332
- flatMap(...args: unknown[]): unknown;
333
- /**
334
- * @deprecated
335
- */
336
- forEach(...args: unknown[]): unknown;
337
- /**
338
- * @deprecated
339
- */
340
- includes(...args: unknown[]): unknown;
341
- /**
342
- * @deprecated
343
- */
344
- indexOf(...args: unknown[]): unknown;
345
- /**
346
- * @deprecated
347
- */
348
- join(...args: unknown[]): unknown;
349
- /**
350
- * @deprecated
351
- */
352
- keys(...args: unknown[]): unknown;
353
- /**
354
- * @deprecated
355
- */
356
- lastIndexOf(...args: unknown[]): unknown;
357
- /**
358
- * @deprecated
359
- */
360
- map(...args: unknown[]): unknown;
361
- /**
362
- * @deprecated
363
- */
364
- pop(...args: unknown[]): any;
365
- /**
366
- * @deprecated
367
- */
368
- push(...args: unknown[]): unknown;
369
- /**
370
- * @deprecated
371
- */
372
- reduce(...args: unknown[]): unknown;
373
- /**
374
- * @deprecated
375
- */
376
- reduceRight(...args: unknown[]): unknown;
377
- /**
378
- * @deprecated
379
- */
380
- reverse(...args: unknown[]): unknown;
381
- /**
382
- * @deprecated
383
- */
384
- shift(...args: unknown[]): unknown;
385
- /**
386
- * @deprecated
387
- */
388
- slice(...args: unknown[]): unknown;
389
- /**
390
- * @deprecated
391
- */
392
- some(...args: unknown[]): unknown;
393
- /**
394
- * @deprecated
395
- */
396
- sort(...args: unknown[]): unknown;
397
- /**
398
- * @deprecated
399
- */
400
- splice(...args: unknown[]): unknown;
401
- /**
402
- * @deprecated
403
- */
404
- toString(...args: unknown[]): unknown;
405
- /**
406
- * @deprecated
407
- */
408
- toLocaleString(...args: unknown[]): unknown;
409
- /**
410
- * @deprecated
411
- */
412
- unshift(...args: unknown[]): unknown;
413
- /**
414
- * @deprecated
415
- */
416
- values(...args: unknown[]): unknown;
1414
+ * Returns an `IterableIterator` over the contained ok value, when this
1415
+ * result is `Ok`.
1416
+ *
1417
+ * Otherwise, returns an empty `IterableIterator`.
1418
+ *
1419
+ * This method should only be called when the `T` type is `Iterable`. This
1420
+ * is enforced with a type constraint. If the ok value is not iterable,
1421
+ * attempting to iterate over it will throw the built-in error.
1422
+ *
1423
+ * @example
1424
+ *
1425
+ * ```ts
1426
+ * const result = Ok([1, 2, 3]);
1427
+ *
1428
+ * for (const n of result.$iter()) {
1429
+ * console.log(n); // 1.. 2.. 3
1430
+ * }
1431
+ * ```
1432
+ *
1433
+ * @example
1434
+ *
1435
+ * ```ts
1436
+ * const result = Err([1, 2, 3]);
1437
+ *
1438
+ * for (const n of result.$iter()) {
1439
+ * console.log(n); // not executed, iterator is empty
1440
+ * }
1441
+ * ```
1442
+ *
1443
+ * @example
1444
+ *
1445
+ * ```ts
1446
+ * const result = Ok<any>(1);
1447
+ *
1448
+ * try {
1449
+ * for (const n of result.$iter()) {}
1450
+ * } catch (err) {
1451
+ * // err is 'TypeError: number 1 is not iterable' in V8
1452
+ * }
1453
+ * ```
1454
+ */
1455
+ $iter<U>(this: Result<Iterable<U>, E>): IterableIterator<U, undefined, unknown>;
417
1456
  }
1457
+ type OkTuple<T> = [err: undefined, value: T];
1458
+ type ErrTuple<E> = [err: E, value: undefined];
1459
+ type ResultLikeAwaitable<T, E> = ResultLike<T, E> | PromiseLike<ResultLike<T, E>>;
1460
+ type ObjectUnionOk<T> = {
1461
+ success: true;
1462
+ data: T;
1463
+ error?: never | undefined;
1464
+ };
1465
+ type ObjectUnionErr<E> = {
1466
+ success: false;
1467
+ data?: never | undefined;
1468
+ error: E;
1469
+ };
1470
+ type Truthy<T> = Exclude<T, false | null | undefined | 0 | 0n | "">;
1471
+ type NonZero<N extends number> = N & (`${N}` extends "0" ? never : N);
1472
+ type NonNegativeOrDecimal<N extends number> = N & (`${N}` extends `-${string}` | `${string}.${string}` ? never : N);