retuple 1.0.0-next.3 → 1.0.0-next.30

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