retuple 1.0.0-next.2 → 1.0.0-next.3

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.cjs CHANGED
@@ -12,13 +12,20 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
12
12
  };
13
13
  var _ResultAsync_inner;
14
14
  Object.defineProperty(exports, "__esModule", { value: true });
15
- exports.Result = exports.RetupleThrownValueError = exports.RetupleExpectFailed = exports.RetupleUnwrapErrFailed = exports.RetupleUnwrapFailed = void 0;
15
+ exports.RetupleInvalidResultError = exports.RetupleThrownValueError = exports.RetupleExpectFailed = exports.RetupleUnwrapErrFailed = exports.RetupleUnwrapFailed = void 0;
16
+ exports.Result = Result;
16
17
  exports.Ok = Ok;
17
18
  exports.Err = Err;
18
- exports.from = from;
19
+ exports.nonNullable = nonNullable;
20
+ exports.truthy = truthy;
19
21
  exports.safe = safe;
20
22
  exports.safeAsync = safeAsync;
21
23
  exports.safePromise = safePromise;
24
+ /**
25
+ * ## Retuple Unwrap Failed
26
+ *
27
+ * An error which occurs when calling `$unwrap` on `Err`.
28
+ */
22
29
  class RetupleUnwrapFailed extends Error {
23
30
  constructor(value, msg = "Unwrap failed") {
24
31
  super(msg, value instanceof Error ? { cause: value } : undefined);
@@ -26,6 +33,11 @@ class RetupleUnwrapFailed extends Error {
26
33
  }
27
34
  }
28
35
  exports.RetupleUnwrapFailed = RetupleUnwrapFailed;
36
+ /**
37
+ * ## Retuple Unwrap Err Failed
38
+ *
39
+ * An error which occurs when calling `$unwrapErr` on `Ok`.
40
+ */
29
41
  class RetupleUnwrapErrFailed extends Error {
30
42
  constructor(value, msg = "Unwrap error failed") {
31
43
  super(msg);
@@ -33,6 +45,12 @@ class RetupleUnwrapErrFailed extends Error {
33
45
  }
34
46
  }
35
47
  exports.RetupleUnwrapErrFailed = RetupleUnwrapErrFailed;
48
+ /**
49
+ * ## Retuple Expect Failed
50
+ *
51
+ * An error which occurs when calling `$expect` on `Err`, and when the value
52
+ * contained in the `Err` is not an instance of `Error`.
53
+ */
36
54
  class RetupleExpectFailed extends Error {
37
55
  constructor(value) {
38
56
  super("Expect failed");
@@ -40,6 +58,13 @@ class RetupleExpectFailed extends Error {
40
58
  }
41
59
  }
42
60
  exports.RetupleExpectFailed = RetupleExpectFailed;
61
+ /**
62
+ * ## Retuple Thrown Value Error
63
+ *
64
+ * An error constructed when a safe function call throws or rejects, when the
65
+ * thrown error or rejected value is not an instance of `Error`, and when no
66
+ * map error function is provided.
67
+ */
43
68
  class RetupleThrownValueError extends Error {
44
69
  constructor(value) {
45
70
  super("Caught value was not an instance of Error");
@@ -47,50 +72,76 @@ class RetupleThrownValueError extends Error {
47
72
  }
48
73
  }
49
74
  exports.RetupleThrownValueError = RetupleThrownValueError;
75
+ /**
76
+ * ## Retuple Invalid Result Error
77
+ *
78
+ * An error constructed when a safe function call throws or rejects, when the
79
+ * thrown error or rejected value is not an instance of `Error`, and when no
80
+ * map error function is provided.
81
+ */
82
+ class RetupleInvalidResultError extends Error {
83
+ constructor(value) {
84
+ super("Constructing a Result from tuple failed, at least one of the values at index 0 or 1 should be undefined");
85
+ this.value = value;
86
+ }
87
+ }
88
+ exports.RetupleInvalidResultError = RetupleInvalidResultError;
50
89
  /**
51
90
  * ## Result
52
91
  *
53
92
  * @TODO
54
93
  */
55
- exports.Result = {
56
- Ok,
57
- Err,
58
- from,
59
- safe,
60
- safeAsync,
61
- safePromise,
62
- };
63
- exports.default = exports.Result;
94
+ function Result(resultLike) {
95
+ const [err, ok] = resultLike;
96
+ if (err === null || err === undefined) {
97
+ return new ResultOk(ok);
98
+ }
99
+ if (ok === null || ok === undefined) {
100
+ return new ResultErr(err);
101
+ }
102
+ throw new RetupleInvalidResultError(resultLike);
103
+ }
104
+ Result.Ok = Ok;
105
+ Result.Err = Err;
106
+ Result.nonNullable = nonNullable;
107
+ Result.truthy = truthy;
108
+ Result.safe = safe;
109
+ Result.safeAsync = safeAsync;
110
+ Result.safePromise = safePromise;
111
+ Object.freeze(Result);
64
112
  function Ok(val) {
65
113
  return new ResultOk(val);
66
114
  }
67
115
  function Err(err) {
68
116
  return new ResultErr(err);
69
117
  }
70
- function from(value, error) {
71
- if (value) {
118
+ function nonNullable(value, error = mapTrue) {
119
+ if (value !== null && value !== undefined) {
72
120
  return new ResultOk(value);
73
121
  }
74
- if (error) {
75
- return new ResultErr(error());
122
+ return new ResultErr(error());
123
+ }
124
+ function truthy(value, error = mapTrue) {
125
+ if (value) {
126
+ return new ResultOk(value);
76
127
  }
77
- return new ResultErr(true);
128
+ return new ResultErr(error());
78
129
  }
79
130
  function safe(f, mapError = ensureError) {
80
131
  try {
81
- return Ok(f());
132
+ return new ResultOk(f());
82
133
  }
83
134
  catch (err) {
84
- return Err(mapError(err));
135
+ return new ResultErr(mapError(err));
85
136
  }
86
137
  }
87
138
  function safeAsync(f, mapError = ensureError) {
88
139
  return new ResultAsync((async () => {
89
140
  try {
90
- return Ok(await f());
141
+ return new ResultOk(await f());
91
142
  }
92
143
  catch (err) {
93
- return Err(await mapError(err));
144
+ return new ResultErr(await mapError(err));
94
145
  }
95
146
  })());
96
147
  }
@@ -108,6 +159,12 @@ class ResultOk extends Array {
108
159
  this[0] = undefined;
109
160
  this[1] = value;
110
161
  }
162
+ toJSON() {
163
+ return this[1];
164
+ }
165
+ $toNativeTuple() {
166
+ return [undefined, this[1]];
167
+ }
111
168
  $value() {
112
169
  return this[1];
113
170
  }
@@ -115,7 +172,7 @@ class ResultOk extends Array {
115
172
  return true;
116
173
  }
117
174
  $isOkAnd(f) {
118
- return f(this[1]);
175
+ return !!f(this[1]);
119
176
  }
120
177
  $isErr() {
121
178
  return false;
@@ -150,6 +207,12 @@ class ResultOk extends Array {
150
207
  $mapOrElse(_def, f) {
151
208
  return new ResultOk(f(this[1]));
152
209
  }
210
+ $assertOr(def, condition = isTruthy) {
211
+ return condition(this[1]) ? this : def;
212
+ }
213
+ $assertOrElse(def, condition = isTruthy) {
214
+ return condition(this[1]) ? this : def();
215
+ }
153
216
  $or() {
154
217
  return this;
155
218
  }
@@ -209,6 +272,12 @@ class ResultErr extends Array {
209
272
  this[0] = err;
210
273
  this[1] = undefined;
211
274
  }
275
+ toJSON() {
276
+ return null;
277
+ }
278
+ $toNativeTuple() {
279
+ return [this[0], undefined];
280
+ }
212
281
  $value() {
213
282
  return this[0];
214
283
  }
@@ -222,7 +291,7 @@ class ResultErr extends Array {
222
291
  return true;
223
292
  }
224
293
  $isErrAnd(f) {
225
- return f(this[0]);
294
+ return !!f(this[0]);
226
295
  }
227
296
  $expect() {
228
297
  if (this[0] instanceof Error) {
@@ -254,6 +323,12 @@ class ResultErr extends Array {
254
323
  $mapOrElse(def) {
255
324
  return new ResultOk(def(this[0]));
256
325
  }
326
+ $assertOr() {
327
+ return this;
328
+ }
329
+ $assertOrElse() {
330
+ return this;
331
+ }
257
332
  $or(or) {
258
333
  return or;
259
334
  }
@@ -391,6 +466,22 @@ class ResultAsync {
391
466
  : new ResultOk(def(res[0]));
392
467
  }));
393
468
  }
469
+ $assertOr(def, condition = isTruthy) {
470
+ return new ResultAsync(__classPrivateFieldGet(this, _ResultAsync_inner, "f").then(async (res) => {
471
+ if (res instanceof ResultErr || condition(res[1])) {
472
+ return res;
473
+ }
474
+ return await def;
475
+ }));
476
+ }
477
+ $assertOrElse(def, condition = isTruthy) {
478
+ return new ResultAsync(__classPrivateFieldGet(this, _ResultAsync_inner, "f").then(async (res) => {
479
+ if (res instanceof ResultErr || condition(res[1])) {
480
+ return res;
481
+ }
482
+ return await def();
483
+ }));
484
+ }
394
485
  /**
395
486
  * @TODO
396
487
  */
@@ -407,9 +498,6 @@ class ResultAsync {
407
498
  return res instanceof ResultErr ? await f(res[0]) : res;
408
499
  }));
409
500
  }
410
- /**
411
- * @TODO
412
- */
413
501
  $orSafe(f, mapError = ensureError) {
414
502
  return new ResultAsync(__classPrivateFieldGet(this, _ResultAsync_inner, "f").then(async (res) => {
415
503
  if (res instanceof ResultOk) {
@@ -453,9 +541,6 @@ class ResultAsync {
453
541
  return res;
454
542
  }));
455
543
  }
456
- /**
457
- * @TODO
458
- */
459
544
  $andSafe(f, mapError = ensureError) {
460
545
  return new ResultAsync(__classPrivateFieldGet(this, _ResultAsync_inner, "f").then(async (res) => {
461
546
  if (res instanceof ResultErr) {
@@ -514,18 +599,9 @@ function ensureError(err) {
514
599
  }
515
600
  return new RetupleThrownValueError(err);
516
601
  }
517
- Object.freeze(exports.Result);
518
- Object.freeze(ResultOk);
519
- Object.freeze(ResultErr);
520
- Object.freeze(ResultAsync);
521
- Object.freeze(RetupleUnwrapFailed);
522
- Object.freeze(RetupleUnwrapErrFailed);
523
- Object.freeze(RetupleExpectFailed);
524
- Object.freeze(RetupleThrownValueError);
525
- Object.freeze(ResultOk.prototype);
526
- Object.freeze(ResultErr.prototype);
527
- Object.freeze(ResultAsync.prototype);
528
- Object.freeze(RetupleUnwrapFailed.prototype);
529
- Object.freeze(RetupleUnwrapErrFailed.prototype);
530
- Object.freeze(RetupleExpectFailed.prototype);
531
- Object.freeze(RetupleThrownValueError.prototype);
602
+ function mapTrue() {
603
+ return true;
604
+ }
605
+ function isTruthy(val) {
606
+ return !!val;
607
+ }
package/dist/index.d.cts CHANGED
@@ -1,57 +1,103 @@
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;
1
6
  export type Ok<T> = OkTuple<T> & Retuple<T, never>;
2
7
  export type Err<E> = ErrTuple<E> & Retuple<never, E>;
3
8
  export type Result<T, E> = (OkTuple<T> | ErrTuple<E>) & Retuple<T, E>;
4
9
  export { type ResultAsync };
5
- export declare class RetupleUnwrapFailed<E = unknown> extends Error {
10
+ /**
11
+ * ## Retuple Unwrap Failed
12
+ *
13
+ * An error which occurs when calling `$unwrap` on `Err`.
14
+ */
15
+ export declare class RetupleUnwrapFailed<const E = unknown> extends Error {
6
16
  value: E;
7
17
  constructor(value: E, msg?: string);
8
18
  }
9
- export declare class RetupleUnwrapErrFailed<T = unknown> extends Error {
19
+ /**
20
+ * ## Retuple Unwrap Err Failed
21
+ *
22
+ * An error which occurs when calling `$unwrapErr` on `Ok`.
23
+ */
24
+ export declare class RetupleUnwrapErrFailed<const T = unknown> extends Error {
10
25
  value: T;
11
26
  constructor(value: T, msg?: string);
12
27
  }
13
- export declare class RetupleExpectFailed<E = unknown> extends Error {
28
+ /**
29
+ * ## Retuple Expect Failed
30
+ *
31
+ * An error which occurs when calling `$expect` on `Err`, and when the value
32
+ * contained in the `Err` is not an instance of `Error`.
33
+ */
34
+ export declare class RetupleExpectFailed<const E = unknown> extends Error {
14
35
  value: E;
15
36
  constructor(value: E);
16
37
  }
38
+ /**
39
+ * ## Retuple Thrown Value Error
40
+ *
41
+ * An error constructed when a safe function call throws or rejects, when the
42
+ * thrown error or rejected value is not an instance of `Error`, and when no
43
+ * map error function is provided.
44
+ */
17
45
  export declare class RetupleThrownValueError extends Error {
18
46
  value: unknown;
19
47
  constructor(value: unknown);
20
48
  }
49
+ /**
50
+ * ## Retuple Invalid Result Error
51
+ *
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.
55
+ */
56
+ export declare class RetupleInvalidResultError extends Error {
57
+ value: unknown[];
58
+ constructor(value: unknown[]);
59
+ }
21
60
  /**
22
61
  * ## Result
23
62
  *
24
63
  * @TODO
25
64
  */
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;
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;
66
+ export declare namespace Result {
67
+ var Ok: typeof import(".").Ok;
68
+ 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;
74
+ }
35
75
  /**
36
76
  * ## Ok
37
77
  *
38
78
  * @TODO
39
79
  */
40
80
  export declare function Ok(): Ok<void>;
41
- export declare function Ok<T>(val: T): Ok<T>;
81
+ export declare function Ok<const T>(val: T): Ok<T>;
42
82
  /**
43
83
  * ## Err
44
84
  *
45
85
  * @TODO
46
86
  */
47
87
  export declare function Err(): Err<void>;
48
- export declare function Err<E>(err: E): Err<E>;
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>;
49
95
  /**
50
96
  * Construct a {@link Result} from a value. If the value is truthy, the result
51
97
  * is `Ok`.
52
98
  */
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>;
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>;
55
101
  /**
56
102
  * Construct a {@link Result} from a synchronous function call. If the function
57
103
  * returns without throwing, the result is `Ok`.
@@ -78,7 +124,7 @@ export declare function safePromise<T, E>(promise: PromiseLike<T>, mapError: (er
78
124
  declare class ResultAsync<T, E> {
79
125
  #private;
80
126
  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>;
127
+ 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>;
82
128
  /**
83
129
  * @TODO
84
130
  */
@@ -102,7 +148,7 @@ declare class ResultAsync<T, E> {
102
148
  /**
103
149
  * @TODO
104
150
  */
105
- $unwrapOrElse<U = T>(this: ResultAsync<T, E>, f: () => U): Promise<T | U>;
151
+ $unwrapOrElse<U>(this: ResultAsync<T, E>, f: () => U): Promise<T | U>;
106
152
  /**
107
153
  * @TODO
108
154
  */
@@ -114,39 +160,52 @@ declare class ResultAsync<T, E> {
114
160
  /**
115
161
  * @TODO
116
162
  */
117
- $mapOr<U>(this: ResultAsync<T, E>, def: U, f: (val: T) => U): ResultAsync<U, E>;
163
+ $mapOr<U, V>(this: ResultAsync<T, E>, def: U, f: (val: T) => V): ResultAsync<U | V, E>;
118
164
  /**
119
165
  * @TODO
120
166
  */
121
- $mapOrElse<U>(this: ResultAsync<T, E>, def: (err: E) => U, f: (val: T) => U): ResultAsync<U, E>;
167
+ $mapOrElse<U, V>(this: ResultAsync<T, E>, def: (err: E) => U, f: (val: T) => V): ResultAsync<U | V, E>;
168
+ /**
169
+ * ## $assertOr
170
+ *
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>;
122
179
  /**
123
180
  * @TODO
124
181
  */
125
- $or<U = T, F = E>(this: ResultAsync<T, E>, or: Result<U, F> | PromiseLike<Result<U, F>>): ResultAsync<T | U, E | F>;
182
+ $or<U, F>(this: ResultAsync<T, E>, or: Result<U, F> | PromiseLike<Result<U, F>>): ResultAsync<T | U, E | F>;
126
183
  /**
127
184
  * @TODO
128
185
  */
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>;
186
+ $orElse<U, F>(this: ResultAsync<T, E>, f: (err: E) => Result<U, F> | PromiseLike<Result<U, F>>): ResultAsync<T | U, E | F>;
130
187
  /**
131
188
  * @TODO
132
189
  */
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>;
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>;
134
192
  /**
135
193
  * @TODO
136
194
  */
137
- $and<U = T, F = E>(this: ResultAsync<T, E>, and: Result<U, F> | PromiseLike<Result<U, F>>): ResultAsync<U, E | F>;
195
+ $and<U, F>(this: ResultAsync<T, E>, and: Result<U, F> | PromiseLike<Result<U, F>>): ResultAsync<U, E | F>;
138
196
  /**
139
197
  * @TODO
140
198
  */
141
- $andThen<U = T, F = E>(this: ResultAsync<T, E>, f: (val: T) => Result<U, F> | PromiseLike<Result<U, F>>): ResultAsync<U, E | F>;
199
+ $andThen<U, F>(this: ResultAsync<T, E>, f: (val: T) => Result<U, F> | PromiseLike<Result<U, F>>): ResultAsync<U, E | F>;
142
200
  /**
143
201
  * @TODO
144
202
  */
145
- $andThrough<F = E>(this: ResultAsync<T, E>, f: (val: T) => Result<any, F> | PromiseLike<Result<any, F>>): ResultAsync<T, E | F>;
203
+ $andThrough<F>(this: ResultAsync<T, E>, f: (val: T) => Result<any, F> | PromiseLike<Result<any, F>>): ResultAsync<T, E | F>;
146
204
  /**
147
205
  * @TODO
148
206
  */
149
- $andSafe<U = T, F = Error>(this: ResultAsync<T, E>, f: (val: T) => U | PromiseLike<U>, mapError?: (err: unknown) => F): ResultAsync<U, E | F>;
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>;
150
209
  /**
151
210
  * @TODO
152
211
  */
@@ -174,23 +233,29 @@ interface Retuple<T, E> {
174
233
  /**
175
234
  * @TODO
176
235
  */
177
- $isOk(this: Result<T, E>): this is Ok<T>;
236
+ $toNativeTuple(this: Result<T, E>): OkTuple<T> | ErrTuple<E>;
178
237
  /**
179
238
  * @TODO
180
239
  */
181
- $isOkAnd<U extends T = T>(this: Result<T, E>, f: ((val: T) => val is U) | ((val: T) => boolean)): this is Ok<U>;
240
+ $value(this: Result<T, E>): T | E;
182
241
  /**
183
242
  * @TODO
184
243
  */
185
- $isErr(this: Result<T, E>): this is Err<E>;
244
+ $isOk(this: Result<T, E>): this is Ok<T>;
186
245
  /**
187
246
  * @TODO
188
247
  */
189
- $isErrAnd<F extends E = E>(this: Result<T, E>, f: ((err: E) => err is F) | ((err: E) => boolean)): this is Err<F>;
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>;
190
250
  /**
191
251
  * @TODO
192
252
  */
193
- $value(this: Result<T, E>): T | E;
253
+ $isErr(this: Result<T, E>): this is Err<E>;
254
+ /**
255
+ * @TODO
256
+ */
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>;
194
259
  /**
195
260
  * @TODO
196
261
  */
@@ -206,11 +271,11 @@ interface Retuple<T, E> {
206
271
  /**
207
272
  * @TODO
208
273
  */
209
- $unwrapOr<U = T>(this: Result<T, E>, def: U): T | U;
274
+ $unwrapOr<const U>(this: Result<T, E>, def: U): T | U;
210
275
  /**
211
276
  * @TODO
212
277
  */
213
- $unwrapOrElse<U = T>(this: Result<T, E>, f: () => U): T | U;
278
+ $unwrapOrElse<U>(this: Result<T, E>, f: () => U): T | U;
214
279
  /**
215
280
  * @TODO
216
281
  */
@@ -222,43 +287,53 @@ interface Retuple<T, E> {
222
287
  /**
223
288
  * @TODO
224
289
  */
225
- $mapOr<U>(this: Result<T, E>, def: U, f: (val: T) => U): Result<U, E>;
290
+ $mapOr<U, V = U>(this: Result<T, E>, def: U, f: (val: T) => V): Result<U | V, E>;
291
+ /**
292
+ * @TODO
293
+ */
294
+ $mapOrElse<U, V = U>(this: Result<T, E>, def: (err: E) => U, f: (val: T) => V): Result<U | V, E>;
295
+ /**
296
+ * @TODO
297
+ */
298
+ $or<U, F>(this: Result<T, E>, or: Result<U, F>): Result<T | U, E | F>;
226
299
  /**
227
300
  * @TODO
228
301
  */
229
- $mapOrElse<U>(this: Result<T, E>, def: (err: E) => U, f: (val: T) => U): Result<U, E>;
302
+ $orElse<U, F>(this: Result<T, E>, f: (err: E) => Result<U, F>): Result<T | U, E | F>;
230
303
  /**
231
304
  * @TODO
232
305
  */
233
- $or<U = T, F = E>(this: Result<T, E>, or: Result<U, F>): Result<T | U, E | F>;
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>;
234
308
  /**
235
309
  * @TODO
236
310
  */
237
- $orElse<U = never, F = never>(this: Result<T, E>, f: (err: E) => Result<U, F>): Result<T | U, E | F>;
311
+ $and<U, F>(this: Result<T, E>, and: Result<U, F>): Result<U, E | F>;
238
312
  /**
239
313
  * @TODO
240
314
  */
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>;
315
+ $andThen<U, F>(this: Result<T, E>, f: (val: T) => Result<U, F>): Result<U, E | F>;
244
316
  /**
245
317
  * @TODO
246
318
  */
247
- $and<U = T, F = E>(this: Result<T, E>, and: Result<U, F>): Result<U, E | F>;
319
+ $andThrough<F>(this: Result<T, E>, f: (val: T) => Result<any, F>): Result<T, E | F>;
248
320
  /**
249
321
  * @TODO
250
322
  */
251
- $andThen<U = never, F = never>(this: Result<T, E>, f: (val: T) => Result<U, F>): Result<U, E | F>;
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>;
252
325
  /**
253
326
  * @TODO
254
327
  */
255
- $andThrough<F = never>(this: Result<T, E>, f: (val: T) => Result<any, F>): Result<T, E | F>;
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>;
256
331
  /**
257
332
  * @TODO
258
333
  */
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>;
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>;
262
337
  /**
263
338
  * @TODO
264
339
  */
package/dist/index.d.ts CHANGED
@@ -1,57 +1,103 @@
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;
1
6
  export type Ok<T> = OkTuple<T> & Retuple<T, never>;
2
7
  export type Err<E> = ErrTuple<E> & Retuple<never, E>;
3
8
  export type Result<T, E> = (OkTuple<T> | ErrTuple<E>) & Retuple<T, E>;
4
9
  export { type ResultAsync };
5
- export declare class RetupleUnwrapFailed<E = unknown> extends Error {
10
+ /**
11
+ * ## Retuple Unwrap Failed
12
+ *
13
+ * An error which occurs when calling `$unwrap` on `Err`.
14
+ */
15
+ export declare class RetupleUnwrapFailed<const E = unknown> extends Error {
6
16
  value: E;
7
17
  constructor(value: E, msg?: string);
8
18
  }
9
- export declare class RetupleUnwrapErrFailed<T = unknown> extends Error {
19
+ /**
20
+ * ## Retuple Unwrap Err Failed
21
+ *
22
+ * An error which occurs when calling `$unwrapErr` on `Ok`.
23
+ */
24
+ export declare class RetupleUnwrapErrFailed<const T = unknown> extends Error {
10
25
  value: T;
11
26
  constructor(value: T, msg?: string);
12
27
  }
13
- export declare class RetupleExpectFailed<E = unknown> extends Error {
28
+ /**
29
+ * ## Retuple Expect Failed
30
+ *
31
+ * An error which occurs when calling `$expect` on `Err`, and when the value
32
+ * contained in the `Err` is not an instance of `Error`.
33
+ */
34
+ export declare class RetupleExpectFailed<const E = unknown> extends Error {
14
35
  value: E;
15
36
  constructor(value: E);
16
37
  }
38
+ /**
39
+ * ## Retuple Thrown Value Error
40
+ *
41
+ * An error constructed when a safe function call throws or rejects, when the
42
+ * thrown error or rejected value is not an instance of `Error`, and when no
43
+ * map error function is provided.
44
+ */
17
45
  export declare class RetupleThrownValueError extends Error {
18
46
  value: unknown;
19
47
  constructor(value: unknown);
20
48
  }
49
+ /**
50
+ * ## Retuple Invalid Result Error
51
+ *
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.
55
+ */
56
+ export declare class RetupleInvalidResultError extends Error {
57
+ value: unknown[];
58
+ constructor(value: unknown[]);
59
+ }
21
60
  /**
22
61
  * ## Result
23
62
  *
24
63
  * @TODO
25
64
  */
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;
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;
66
+ export declare namespace Result {
67
+ var Ok: typeof import(".").Ok;
68
+ 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;
74
+ }
35
75
  /**
36
76
  * ## Ok
37
77
  *
38
78
  * @TODO
39
79
  */
40
80
  export declare function Ok(): Ok<void>;
41
- export declare function Ok<T>(val: T): Ok<T>;
81
+ export declare function Ok<const T>(val: T): Ok<T>;
42
82
  /**
43
83
  * ## Err
44
84
  *
45
85
  * @TODO
46
86
  */
47
87
  export declare function Err(): Err<void>;
48
- export declare function Err<E>(err: E): Err<E>;
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>;
49
95
  /**
50
96
  * Construct a {@link Result} from a value. If the value is truthy, the result
51
97
  * is `Ok`.
52
98
  */
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>;
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>;
55
101
  /**
56
102
  * Construct a {@link Result} from a synchronous function call. If the function
57
103
  * returns without throwing, the result is `Ok`.
@@ -78,7 +124,7 @@ export declare function safePromise<T, E>(promise: PromiseLike<T>, mapError: (er
78
124
  declare class ResultAsync<T, E> {
79
125
  #private;
80
126
  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>;
127
+ 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>;
82
128
  /**
83
129
  * @TODO
84
130
  */
@@ -102,7 +148,7 @@ declare class ResultAsync<T, E> {
102
148
  /**
103
149
  * @TODO
104
150
  */
105
- $unwrapOrElse<U = T>(this: ResultAsync<T, E>, f: () => U): Promise<T | U>;
151
+ $unwrapOrElse<U>(this: ResultAsync<T, E>, f: () => U): Promise<T | U>;
106
152
  /**
107
153
  * @TODO
108
154
  */
@@ -114,39 +160,52 @@ declare class ResultAsync<T, E> {
114
160
  /**
115
161
  * @TODO
116
162
  */
117
- $mapOr<U>(this: ResultAsync<T, E>, def: U, f: (val: T) => U): ResultAsync<U, E>;
163
+ $mapOr<U, V>(this: ResultAsync<T, E>, def: U, f: (val: T) => V): ResultAsync<U | V, E>;
118
164
  /**
119
165
  * @TODO
120
166
  */
121
- $mapOrElse<U>(this: ResultAsync<T, E>, def: (err: E) => U, f: (val: T) => U): ResultAsync<U, E>;
167
+ $mapOrElse<U, V>(this: ResultAsync<T, E>, def: (err: E) => U, f: (val: T) => V): ResultAsync<U | V, E>;
168
+ /**
169
+ * ## $assertOr
170
+ *
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>;
122
179
  /**
123
180
  * @TODO
124
181
  */
125
- $or<U = T, F = E>(this: ResultAsync<T, E>, or: Result<U, F> | PromiseLike<Result<U, F>>): ResultAsync<T | U, E | F>;
182
+ $or<U, F>(this: ResultAsync<T, E>, or: Result<U, F> | PromiseLike<Result<U, F>>): ResultAsync<T | U, E | F>;
126
183
  /**
127
184
  * @TODO
128
185
  */
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>;
186
+ $orElse<U, F>(this: ResultAsync<T, E>, f: (err: E) => Result<U, F> | PromiseLike<Result<U, F>>): ResultAsync<T | U, E | F>;
130
187
  /**
131
188
  * @TODO
132
189
  */
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>;
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>;
134
192
  /**
135
193
  * @TODO
136
194
  */
137
- $and<U = T, F = E>(this: ResultAsync<T, E>, and: Result<U, F> | PromiseLike<Result<U, F>>): ResultAsync<U, E | F>;
195
+ $and<U, F>(this: ResultAsync<T, E>, and: Result<U, F> | PromiseLike<Result<U, F>>): ResultAsync<U, E | F>;
138
196
  /**
139
197
  * @TODO
140
198
  */
141
- $andThen<U = T, F = E>(this: ResultAsync<T, E>, f: (val: T) => Result<U, F> | PromiseLike<Result<U, F>>): ResultAsync<U, E | F>;
199
+ $andThen<U, F>(this: ResultAsync<T, E>, f: (val: T) => Result<U, F> | PromiseLike<Result<U, F>>): ResultAsync<U, E | F>;
142
200
  /**
143
201
  * @TODO
144
202
  */
145
- $andThrough<F = E>(this: ResultAsync<T, E>, f: (val: T) => Result<any, F> | PromiseLike<Result<any, F>>): ResultAsync<T, E | F>;
203
+ $andThrough<F>(this: ResultAsync<T, E>, f: (val: T) => Result<any, F> | PromiseLike<Result<any, F>>): ResultAsync<T, E | F>;
146
204
  /**
147
205
  * @TODO
148
206
  */
149
- $andSafe<U = T, F = Error>(this: ResultAsync<T, E>, f: (val: T) => U | PromiseLike<U>, mapError?: (err: unknown) => F): ResultAsync<U, E | F>;
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>;
150
209
  /**
151
210
  * @TODO
152
211
  */
@@ -174,23 +233,29 @@ interface Retuple<T, E> {
174
233
  /**
175
234
  * @TODO
176
235
  */
177
- $isOk(this: Result<T, E>): this is Ok<T>;
236
+ $toNativeTuple(this: Result<T, E>): OkTuple<T> | ErrTuple<E>;
178
237
  /**
179
238
  * @TODO
180
239
  */
181
- $isOkAnd<U extends T = T>(this: Result<T, E>, f: ((val: T) => val is U) | ((val: T) => boolean)): this is Ok<U>;
240
+ $value(this: Result<T, E>): T | E;
182
241
  /**
183
242
  * @TODO
184
243
  */
185
- $isErr(this: Result<T, E>): this is Err<E>;
244
+ $isOk(this: Result<T, E>): this is Ok<T>;
186
245
  /**
187
246
  * @TODO
188
247
  */
189
- $isErrAnd<F extends E = E>(this: Result<T, E>, f: ((err: E) => err is F) | ((err: E) => boolean)): this is Err<F>;
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>;
190
250
  /**
191
251
  * @TODO
192
252
  */
193
- $value(this: Result<T, E>): T | E;
253
+ $isErr(this: Result<T, E>): this is Err<E>;
254
+ /**
255
+ * @TODO
256
+ */
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>;
194
259
  /**
195
260
  * @TODO
196
261
  */
@@ -206,11 +271,11 @@ interface Retuple<T, E> {
206
271
  /**
207
272
  * @TODO
208
273
  */
209
- $unwrapOr<U = T>(this: Result<T, E>, def: U): T | U;
274
+ $unwrapOr<const U>(this: Result<T, E>, def: U): T | U;
210
275
  /**
211
276
  * @TODO
212
277
  */
213
- $unwrapOrElse<U = T>(this: Result<T, E>, f: () => U): T | U;
278
+ $unwrapOrElse<U>(this: Result<T, E>, f: () => U): T | U;
214
279
  /**
215
280
  * @TODO
216
281
  */
@@ -222,43 +287,53 @@ interface Retuple<T, E> {
222
287
  /**
223
288
  * @TODO
224
289
  */
225
- $mapOr<U>(this: Result<T, E>, def: U, f: (val: T) => U): Result<U, E>;
290
+ $mapOr<U, V = U>(this: Result<T, E>, def: U, f: (val: T) => V): Result<U | V, E>;
291
+ /**
292
+ * @TODO
293
+ */
294
+ $mapOrElse<U, V = U>(this: Result<T, E>, def: (err: E) => U, f: (val: T) => V): Result<U | V, E>;
295
+ /**
296
+ * @TODO
297
+ */
298
+ $or<U, F>(this: Result<T, E>, or: Result<U, F>): Result<T | U, E | F>;
226
299
  /**
227
300
  * @TODO
228
301
  */
229
- $mapOrElse<U>(this: Result<T, E>, def: (err: E) => U, f: (val: T) => U): Result<U, E>;
302
+ $orElse<U, F>(this: Result<T, E>, f: (err: E) => Result<U, F>): Result<T | U, E | F>;
230
303
  /**
231
304
  * @TODO
232
305
  */
233
- $or<U = T, F = E>(this: Result<T, E>, or: Result<U, F>): Result<T | U, E | F>;
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>;
234
308
  /**
235
309
  * @TODO
236
310
  */
237
- $orElse<U = never, F = never>(this: Result<T, E>, f: (err: E) => Result<U, F>): Result<T | U, E | F>;
311
+ $and<U, F>(this: Result<T, E>, and: Result<U, F>): Result<U, E | F>;
238
312
  /**
239
313
  * @TODO
240
314
  */
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>;
315
+ $andThen<U, F>(this: Result<T, E>, f: (val: T) => Result<U, F>): Result<U, E | F>;
244
316
  /**
245
317
  * @TODO
246
318
  */
247
- $and<U = T, F = E>(this: Result<T, E>, and: Result<U, F>): Result<U, E | F>;
319
+ $andThrough<F>(this: Result<T, E>, f: (val: T) => Result<any, F>): Result<T, E | F>;
248
320
  /**
249
321
  * @TODO
250
322
  */
251
- $andThen<U = never, F = never>(this: Result<T, E>, f: (val: T) => Result<U, F>): Result<U, E | F>;
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>;
252
325
  /**
253
326
  * @TODO
254
327
  */
255
- $andThrough<F = never>(this: Result<T, E>, f: (val: T) => Result<any, F>): Result<T, E | F>;
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>;
256
331
  /**
257
332
  * @TODO
258
333
  */
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>;
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>;
262
337
  /**
263
338
  * @TODO
264
339
  */
package/dist/index.js CHANGED
@@ -10,74 +10,122 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
10
10
  return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
11
11
  };
12
12
  var _ResultAsync_inner;
13
+ /**
14
+ * ## Retuple Unwrap Failed
15
+ *
16
+ * An error which occurs when calling `$unwrap` on `Err`.
17
+ */
13
18
  export class RetupleUnwrapFailed extends Error {
14
19
  constructor(value, msg = "Unwrap failed") {
15
20
  super(msg, value instanceof Error ? { cause: value } : undefined);
16
21
  this.value = value;
17
22
  }
18
23
  }
24
+ /**
25
+ * ## Retuple Unwrap Err Failed
26
+ *
27
+ * An error which occurs when calling `$unwrapErr` on `Ok`.
28
+ */
19
29
  export class RetupleUnwrapErrFailed extends Error {
20
30
  constructor(value, msg = "Unwrap error failed") {
21
31
  super(msg);
22
32
  this.value = value;
23
33
  }
24
34
  }
35
+ /**
36
+ * ## Retuple Expect Failed
37
+ *
38
+ * An error which occurs when calling `$expect` on `Err`, and when the value
39
+ * contained in the `Err` is not an instance of `Error`.
40
+ */
25
41
  export class RetupleExpectFailed extends Error {
26
42
  constructor(value) {
27
43
  super("Expect failed");
28
44
  this.value = value;
29
45
  }
30
46
  }
47
+ /**
48
+ * ## Retuple Thrown Value Error
49
+ *
50
+ * An error constructed when a safe function call throws or rejects, when the
51
+ * thrown error or rejected value is not an instance of `Error`, and when no
52
+ * map error function is provided.
53
+ */
31
54
  export class RetupleThrownValueError extends Error {
32
55
  constructor(value) {
33
56
  super("Caught value was not an instance of Error");
34
57
  this.value = value;
35
58
  }
36
59
  }
60
+ /**
61
+ * ## Retuple Invalid Result Error
62
+ *
63
+ * An error constructed when a safe function call throws or rejects, when the
64
+ * thrown error or rejected value is not an instance of `Error`, and when no
65
+ * map error function is provided.
66
+ */
67
+ export class RetupleInvalidResultError extends Error {
68
+ constructor(value) {
69
+ super("Constructing a Result from tuple failed, at least one of the values at index 0 or 1 should be undefined");
70
+ this.value = value;
71
+ }
72
+ }
37
73
  /**
38
74
  * ## Result
39
75
  *
40
76
  * @TODO
41
77
  */
42
- export const Result = {
43
- Ok,
44
- Err,
45
- from,
46
- safe,
47
- safeAsync,
48
- safePromise,
49
- };
50
- export default Result;
78
+ export function Result(resultLike) {
79
+ const [err, ok] = resultLike;
80
+ if (err === null || err === undefined) {
81
+ return new ResultOk(ok);
82
+ }
83
+ if (ok === null || ok === undefined) {
84
+ return new ResultErr(err);
85
+ }
86
+ throw new RetupleInvalidResultError(resultLike);
87
+ }
88
+ Result.Ok = Ok;
89
+ Result.Err = Err;
90
+ Result.nonNullable = nonNullable;
91
+ Result.truthy = truthy;
92
+ Result.safe = safe;
93
+ Result.safeAsync = safeAsync;
94
+ Result.safePromise = safePromise;
95
+ Object.freeze(Result);
51
96
  export function Ok(val) {
52
97
  return new ResultOk(val);
53
98
  }
54
99
  export function Err(err) {
55
100
  return new ResultErr(err);
56
101
  }
57
- export function from(value, error) {
58
- if (value) {
102
+ export function nonNullable(value, error = mapTrue) {
103
+ if (value !== null && value !== undefined) {
59
104
  return new ResultOk(value);
60
105
  }
61
- if (error) {
62
- return new ResultErr(error());
106
+ return new ResultErr(error());
107
+ }
108
+ export function truthy(value, error = mapTrue) {
109
+ if (value) {
110
+ return new ResultOk(value);
63
111
  }
64
- return new ResultErr(true);
112
+ return new ResultErr(error());
65
113
  }
66
114
  export function safe(f, mapError = ensureError) {
67
115
  try {
68
- return Ok(f());
116
+ return new ResultOk(f());
69
117
  }
70
118
  catch (err) {
71
- return Err(mapError(err));
119
+ return new ResultErr(mapError(err));
72
120
  }
73
121
  }
74
122
  export function safeAsync(f, mapError = ensureError) {
75
123
  return new ResultAsync((async () => {
76
124
  try {
77
- return Ok(await f());
125
+ return new ResultOk(await f());
78
126
  }
79
127
  catch (err) {
80
- return Err(await mapError(err));
128
+ return new ResultErr(await mapError(err));
81
129
  }
82
130
  })());
83
131
  }
@@ -95,6 +143,12 @@ class ResultOk extends Array {
95
143
  this[0] = undefined;
96
144
  this[1] = value;
97
145
  }
146
+ toJSON() {
147
+ return this[1];
148
+ }
149
+ $toNativeTuple() {
150
+ return [undefined, this[1]];
151
+ }
98
152
  $value() {
99
153
  return this[1];
100
154
  }
@@ -102,7 +156,7 @@ class ResultOk extends Array {
102
156
  return true;
103
157
  }
104
158
  $isOkAnd(f) {
105
- return f(this[1]);
159
+ return !!f(this[1]);
106
160
  }
107
161
  $isErr() {
108
162
  return false;
@@ -137,6 +191,12 @@ class ResultOk extends Array {
137
191
  $mapOrElse(_def, f) {
138
192
  return new ResultOk(f(this[1]));
139
193
  }
194
+ $assertOr(def, condition = isTruthy) {
195
+ return condition(this[1]) ? this : def;
196
+ }
197
+ $assertOrElse(def, condition = isTruthy) {
198
+ return condition(this[1]) ? this : def();
199
+ }
140
200
  $or() {
141
201
  return this;
142
202
  }
@@ -196,6 +256,12 @@ class ResultErr extends Array {
196
256
  this[0] = err;
197
257
  this[1] = undefined;
198
258
  }
259
+ toJSON() {
260
+ return null;
261
+ }
262
+ $toNativeTuple() {
263
+ return [this[0], undefined];
264
+ }
199
265
  $value() {
200
266
  return this[0];
201
267
  }
@@ -209,7 +275,7 @@ class ResultErr extends Array {
209
275
  return true;
210
276
  }
211
277
  $isErrAnd(f) {
212
- return f(this[0]);
278
+ return !!f(this[0]);
213
279
  }
214
280
  $expect() {
215
281
  if (this[0] instanceof Error) {
@@ -241,6 +307,12 @@ class ResultErr extends Array {
241
307
  $mapOrElse(def) {
242
308
  return new ResultOk(def(this[0]));
243
309
  }
310
+ $assertOr() {
311
+ return this;
312
+ }
313
+ $assertOrElse() {
314
+ return this;
315
+ }
244
316
  $or(or) {
245
317
  return or;
246
318
  }
@@ -378,6 +450,22 @@ class ResultAsync {
378
450
  : new ResultOk(def(res[0]));
379
451
  }));
380
452
  }
453
+ $assertOr(def, condition = isTruthy) {
454
+ return new ResultAsync(__classPrivateFieldGet(this, _ResultAsync_inner, "f").then(async (res) => {
455
+ if (res instanceof ResultErr || condition(res[1])) {
456
+ return res;
457
+ }
458
+ return await def;
459
+ }));
460
+ }
461
+ $assertOrElse(def, condition = isTruthy) {
462
+ return new ResultAsync(__classPrivateFieldGet(this, _ResultAsync_inner, "f").then(async (res) => {
463
+ if (res instanceof ResultErr || condition(res[1])) {
464
+ return res;
465
+ }
466
+ return await def();
467
+ }));
468
+ }
381
469
  /**
382
470
  * @TODO
383
471
  */
@@ -394,9 +482,6 @@ class ResultAsync {
394
482
  return res instanceof ResultErr ? await f(res[0]) : res;
395
483
  }));
396
484
  }
397
- /**
398
- * @TODO
399
- */
400
485
  $orSafe(f, mapError = ensureError) {
401
486
  return new ResultAsync(__classPrivateFieldGet(this, _ResultAsync_inner, "f").then(async (res) => {
402
487
  if (res instanceof ResultOk) {
@@ -440,9 +525,6 @@ class ResultAsync {
440
525
  return res;
441
526
  }));
442
527
  }
443
- /**
444
- * @TODO
445
- */
446
528
  $andSafe(f, mapError = ensureError) {
447
529
  return new ResultAsync(__classPrivateFieldGet(this, _ResultAsync_inner, "f").then(async (res) => {
448
530
  if (res instanceof ResultErr) {
@@ -501,18 +583,9 @@ function ensureError(err) {
501
583
  }
502
584
  return new RetupleThrownValueError(err);
503
585
  }
504
- Object.freeze(Result);
505
- Object.freeze(ResultOk);
506
- Object.freeze(ResultErr);
507
- Object.freeze(ResultAsync);
508
- Object.freeze(RetupleUnwrapFailed);
509
- Object.freeze(RetupleUnwrapErrFailed);
510
- Object.freeze(RetupleExpectFailed);
511
- Object.freeze(RetupleThrownValueError);
512
- Object.freeze(ResultOk.prototype);
513
- Object.freeze(ResultErr.prototype);
514
- Object.freeze(ResultAsync.prototype);
515
- Object.freeze(RetupleUnwrapFailed.prototype);
516
- Object.freeze(RetupleUnwrapErrFailed.prototype);
517
- Object.freeze(RetupleExpectFailed.prototype);
518
- Object.freeze(RetupleThrownValueError.prototype);
586
+ function mapTrue() {
587
+ return true;
588
+ }
589
+ function isTruthy(val) {
590
+ return !!val;
591
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "retuple",
3
- "version": "1.0.0-next.2",
3
+ "version": "1.0.0-next.3",
4
4
  "scripts": {
5
5
  "test": "vitest",
6
6
  "lint": "eslint . --ext .ts -c eslint.config.mjs --fix",