ts-data-forge 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +201 -0
- package/README.md +534 -0
- package/package.json +101 -0
- package/src/array/array-utils-creation.test.mts +443 -0
- package/src/array/array-utils-modification.test.mts +197 -0
- package/src/array/array-utils-overload-type-error.test.mts +149 -0
- package/src/array/array-utils-reducing-value.test.mts +425 -0
- package/src/array/array-utils-search.test.mts +169 -0
- package/src/array/array-utils-set-op.test.mts +335 -0
- package/src/array/array-utils-slice-clamped.test.mts +113 -0
- package/src/array/array-utils-slicing.test.mts +316 -0
- package/src/array/array-utils-transformation.test.mts +790 -0
- package/src/array/array-utils-validation.test.mts +492 -0
- package/src/array/array-utils.mts +4000 -0
- package/src/array/array.test.mts +146 -0
- package/src/array/index.mts +2 -0
- package/src/array/tuple-utils.mts +519 -0
- package/src/array/tuple-utils.test.mts +518 -0
- package/src/collections/imap-mapped.mts +801 -0
- package/src/collections/imap-mapped.test.mts +860 -0
- package/src/collections/imap.mts +651 -0
- package/src/collections/imap.test.mts +932 -0
- package/src/collections/index.mts +6 -0
- package/src/collections/iset-mapped.mts +889 -0
- package/src/collections/iset-mapped.test.mts +1187 -0
- package/src/collections/iset.mts +682 -0
- package/src/collections/iset.test.mts +1084 -0
- package/src/collections/queue.mts +390 -0
- package/src/collections/queue.test.mts +282 -0
- package/src/collections/stack.mts +423 -0
- package/src/collections/stack.test.mts +225 -0
- package/src/expect-type.mts +206 -0
- package/src/functional/index.mts +4 -0
- package/src/functional/match.mts +300 -0
- package/src/functional/match.test.mts +177 -0
- package/src/functional/optional.mts +733 -0
- package/src/functional/optional.test.mts +619 -0
- package/src/functional/pipe.mts +212 -0
- package/src/functional/pipe.test.mts +85 -0
- package/src/functional/result.mts +1134 -0
- package/src/functional/result.test.mts +777 -0
- package/src/globals.d.mts +38 -0
- package/src/guard/has-key.mts +119 -0
- package/src/guard/has-key.test.mts +219 -0
- package/src/guard/index.mts +7 -0
- package/src/guard/is-non-empty-string.mts +108 -0
- package/src/guard/is-non-empty-string.test.mts +91 -0
- package/src/guard/is-non-null-object.mts +106 -0
- package/src/guard/is-non-null-object.test.mts +90 -0
- package/src/guard/is-primitive.mts +165 -0
- package/src/guard/is-primitive.test.mts +102 -0
- package/src/guard/is-record.mts +153 -0
- package/src/guard/is-record.test.mts +112 -0
- package/src/guard/is-type.mts +450 -0
- package/src/guard/is-type.test.mts +496 -0
- package/src/guard/key-is-in.mts +163 -0
- package/src/guard/key-is-in.test.mts +19 -0
- package/src/index.mts +10 -0
- package/src/iterator/index.mts +1 -0
- package/src/iterator/range.mts +120 -0
- package/src/iterator/range.test.mts +33 -0
- package/src/json/index.mts +1 -0
- package/src/json/json.mts +711 -0
- package/src/json/json.test.mts +628 -0
- package/src/number/branded-types/finite-number.mts +354 -0
- package/src/number/branded-types/finite-number.test.mts +135 -0
- package/src/number/branded-types/index.mts +26 -0
- package/src/number/branded-types/int.mts +278 -0
- package/src/number/branded-types/int.test.mts +140 -0
- package/src/number/branded-types/int16.mts +192 -0
- package/src/number/branded-types/int16.test.mts +170 -0
- package/src/number/branded-types/int32.mts +193 -0
- package/src/number/branded-types/int32.test.mts +170 -0
- package/src/number/branded-types/non-negative-finite-number.mts +223 -0
- package/src/number/branded-types/non-negative-finite-number.test.mts +188 -0
- package/src/number/branded-types/non-negative-int16.mts +187 -0
- package/src/number/branded-types/non-negative-int16.test.mts +201 -0
- package/src/number/branded-types/non-negative-int32.mts +187 -0
- package/src/number/branded-types/non-negative-int32.test.mts +204 -0
- package/src/number/branded-types/non-zero-finite-number.mts +229 -0
- package/src/number/branded-types/non-zero-finite-number.test.mts +198 -0
- package/src/number/branded-types/non-zero-int.mts +167 -0
- package/src/number/branded-types/non-zero-int.test.mts +177 -0
- package/src/number/branded-types/non-zero-int16.mts +196 -0
- package/src/number/branded-types/non-zero-int16.test.mts +195 -0
- package/src/number/branded-types/non-zero-int32.mts +196 -0
- package/src/number/branded-types/non-zero-int32.test.mts +197 -0
- package/src/number/branded-types/non-zero-safe-int.mts +196 -0
- package/src/number/branded-types/non-zero-safe-int.test.mts +232 -0
- package/src/number/branded-types/non-zero-uint16.mts +189 -0
- package/src/number/branded-types/non-zero-uint16.test.mts +199 -0
- package/src/number/branded-types/non-zero-uint32.mts +189 -0
- package/src/number/branded-types/non-zero-uint32.test.mts +199 -0
- package/src/number/branded-types/positive-finite-number.mts +241 -0
- package/src/number/branded-types/positive-finite-number.test.mts +204 -0
- package/src/number/branded-types/positive-int.mts +304 -0
- package/src/number/branded-types/positive-int.test.mts +176 -0
- package/src/number/branded-types/positive-int16.mts +188 -0
- package/src/number/branded-types/positive-int16.test.mts +197 -0
- package/src/number/branded-types/positive-int32.mts +188 -0
- package/src/number/branded-types/positive-int32.test.mts +197 -0
- package/src/number/branded-types/positive-safe-int.mts +187 -0
- package/src/number/branded-types/positive-safe-int.test.mts +210 -0
- package/src/number/branded-types/positive-uint16.mts +188 -0
- package/src/number/branded-types/positive-uint16.test.mts +203 -0
- package/src/number/branded-types/positive-uint32.mts +188 -0
- package/src/number/branded-types/positive-uint32.test.mts +203 -0
- package/src/number/branded-types/safe-int.mts +291 -0
- package/src/number/branded-types/safe-int.test.mts +170 -0
- package/src/number/branded-types/safe-uint.mts +187 -0
- package/src/number/branded-types/safe-uint.test.mts +176 -0
- package/src/number/branded-types/uint.mts +179 -0
- package/src/number/branded-types/uint.test.mts +158 -0
- package/src/number/branded-types/uint16.mts +186 -0
- package/src/number/branded-types/uint16.test.mts +170 -0
- package/src/number/branded-types/uint32.mts +218 -0
- package/src/number/branded-types/uint32.test.mts +170 -0
- package/src/number/enum/index.mts +2 -0
- package/src/number/enum/int8.mts +344 -0
- package/src/number/enum/int8.test.mts +180 -0
- package/src/number/enum/uint8.mts +293 -0
- package/src/number/enum/uint8.test.mts +164 -0
- package/src/number/index.mts +4 -0
- package/src/number/num.mts +604 -0
- package/src/number/num.test.mts +242 -0
- package/src/number/refined-number-utils.mts +566 -0
- package/src/object/index.mts +1 -0
- package/src/object/object.mts +447 -0
- package/src/object/object.test.mts +124 -0
- package/src/others/cast-mutable.mts +113 -0
- package/src/others/cast-readonly.mts +192 -0
- package/src/others/cast-readonly.test.mts +89 -0
- package/src/others/if-then.mts +98 -0
- package/src/others/if-then.test.mts +75 -0
- package/src/others/index.mts +7 -0
- package/src/others/map-nullable.mts +172 -0
- package/src/others/map-nullable.test.mts +297 -0
- package/src/others/memoize-function.mts +196 -0
- package/src/others/memoize-function.test.mts +168 -0
- package/src/others/tuple.mts +160 -0
- package/src/others/tuple.test.mts +11 -0
- package/src/others/unknown-to-string.mts +215 -0
- package/src/others/unknown-to-string.test.mts +114 -0
|
@@ -0,0 +1,777 @@
|
|
|
1
|
+
import { expectType } from '../expect-type.mjs';
|
|
2
|
+
import { Optional } from './optional.mjs';
|
|
3
|
+
import { pipe } from './pipe.mjs';
|
|
4
|
+
import { Result } from './result.mjs';
|
|
5
|
+
|
|
6
|
+
describe('Result', () => {
|
|
7
|
+
describe('ok', () => {
|
|
8
|
+
test('creates Ok result', () => {
|
|
9
|
+
const result = Result.ok(42);
|
|
10
|
+
expect(Result.isOk(result)).toBe(true);
|
|
11
|
+
expect(Result.isErr(result)).toBe(false);
|
|
12
|
+
expect(result.value).toBe(42);
|
|
13
|
+
expectType<typeof result, Result<number, never>>('<=');
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
test('creates Ok result with string', () => {
|
|
17
|
+
const result = Result.ok('success');
|
|
18
|
+
expect(Result.isOk(result)).toBe(true);
|
|
19
|
+
expect(result.value).toBe('success');
|
|
20
|
+
expectType<typeof result, Result<string, never>>('<=');
|
|
21
|
+
});
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
describe('err', () => {
|
|
25
|
+
test('creates Err result', () => {
|
|
26
|
+
const result = Result.err('error message');
|
|
27
|
+
expect(Result.isErr(result)).toBe(true);
|
|
28
|
+
expect(Result.isOk(result)).toBe(false);
|
|
29
|
+
expect(result.value).toBe('error message');
|
|
30
|
+
expectType<typeof result, Result<never, string>>('<=');
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
test('creates Err result with number', () => {
|
|
34
|
+
const result = Result.err(404);
|
|
35
|
+
expect(Result.isErr(result)).toBe(true);
|
|
36
|
+
expect(result.value).toBe(404);
|
|
37
|
+
expectType<typeof result, Result<never, number>>('<=');
|
|
38
|
+
});
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
describe('isOk', () => {
|
|
42
|
+
test('type guard for Ok results', () => {
|
|
43
|
+
const result: Result<number, string> = Result.ok(42);
|
|
44
|
+
if (Result.isOk(result)) {
|
|
45
|
+
expectType<typeof result, Result.Ok<number>>('<=');
|
|
46
|
+
expect(result.value).toBe(42);
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
test('returns false for Err results', () => {
|
|
51
|
+
const result: Result<number, string> = Result.err('error');
|
|
52
|
+
expect(Result.isOk(result)).toBe(false);
|
|
53
|
+
});
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
describe('isErr', () => {
|
|
57
|
+
test('type guard for Err results', () => {
|
|
58
|
+
const result: Result<number, string> = Result.err('error');
|
|
59
|
+
if (Result.isErr(result)) {
|
|
60
|
+
expectType<typeof result, Result.Err<string>>('<=');
|
|
61
|
+
expect(result.value).toBe('error');
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
test('returns false for Ok results', () => {
|
|
66
|
+
const result: Result<number, string> = Result.ok(42);
|
|
67
|
+
expect(Result.isErr(result)).toBe(false);
|
|
68
|
+
});
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
describe('isResult', () => {
|
|
72
|
+
test('recognizes Ok results', () => {
|
|
73
|
+
const result = Result.ok(42);
|
|
74
|
+
expect(Result.isResult(result)).toBe(true);
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
test('recognizes Err results', () => {
|
|
78
|
+
const result = Result.err('error');
|
|
79
|
+
expect(Result.isResult(result)).toBe(true);
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
test('rejects non-Result values', () => {
|
|
83
|
+
expect(Result.isResult(42)).toBe(false);
|
|
84
|
+
expect(Result.isResult('string')).toBe(false);
|
|
85
|
+
expect(Result.isResult(null)).toBe(false);
|
|
86
|
+
expect(Result.isResult(undefined)).toBe(false);
|
|
87
|
+
expect(Result.isResult({})).toBe(false);
|
|
88
|
+
expect(Result.isResult({ type: 'unknown', value: 42 })).toBe(false);
|
|
89
|
+
});
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
describe('map', () => {
|
|
93
|
+
test('maps Ok result', () => {
|
|
94
|
+
const result = Result.ok(5);
|
|
95
|
+
const mapped = Result.map(result, (x) => x * 2);
|
|
96
|
+
expect(Result.isOk(mapped)).toBe(true);
|
|
97
|
+
if (Result.isOk(mapped)) {
|
|
98
|
+
expect(mapped.value).toBe(10);
|
|
99
|
+
}
|
|
100
|
+
expectType<typeof mapped, Result<number, never>>('<=');
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
test('preserves Err result', () => {
|
|
104
|
+
const result: Result<number, string> = Result.err('error');
|
|
105
|
+
const mapped = Result.map(result, (x) => x * 2);
|
|
106
|
+
expect(Result.isErr(mapped)).toBe(true);
|
|
107
|
+
if (Result.isErr(mapped)) {
|
|
108
|
+
expect(mapped.value).toBe('error');
|
|
109
|
+
}
|
|
110
|
+
expectType<typeof mapped, Result<number, string>>('<=');
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
test('should support curried form', () => {
|
|
114
|
+
const doubler = Result.map((x: number) => x * 2);
|
|
115
|
+
|
|
116
|
+
const okResult = Result.ok(5);
|
|
117
|
+
const mapped = doubler(okResult);
|
|
118
|
+
|
|
119
|
+
expect(Result.isOk(mapped)).toBe(true);
|
|
120
|
+
if (Result.isOk(mapped)) {
|
|
121
|
+
expect(mapped.value).toBe(10);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
const errResult: Result<number, string> = Result.err('error');
|
|
125
|
+
const mappedErr = doubler(errResult);
|
|
126
|
+
expect(Result.isErr(mappedErr)).toBe(true);
|
|
127
|
+
if (Result.isErr(mappedErr)) {
|
|
128
|
+
expect(mappedErr.value).toBe('error');
|
|
129
|
+
}
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
test('should work with pipe when curried', () => {
|
|
133
|
+
const doubler = Result.map((x: number) => x * 2);
|
|
134
|
+
const toStringFn = Result.map((x: number) => x.toString());
|
|
135
|
+
|
|
136
|
+
const result = pipe(Result.ok(5)).map(doubler).map(toStringFn).value;
|
|
137
|
+
|
|
138
|
+
expect(Result.isOk(result)).toBe(true);
|
|
139
|
+
if (Result.isOk(result)) {
|
|
140
|
+
expect(result.value).toBe('10');
|
|
141
|
+
}
|
|
142
|
+
});
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
describe('mapErr', () => {
|
|
146
|
+
test('maps Err result', () => {
|
|
147
|
+
const result: Result<number, string> = Result.err('error');
|
|
148
|
+
const mapped = Result.mapErr(result, (e) => e.toUpperCase());
|
|
149
|
+
expect(Result.isErr(mapped)).toBe(true);
|
|
150
|
+
if (Result.isErr(mapped)) {
|
|
151
|
+
expect(mapped.value).toBe('ERROR');
|
|
152
|
+
}
|
|
153
|
+
expectType<typeof mapped, Result<number, string>>('<=');
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
test('preserves Ok result', () => {
|
|
157
|
+
const result: Result<number, string> = Result.ok(42);
|
|
158
|
+
const mapped = Result.mapErr(result, (e: string) => e.toUpperCase());
|
|
159
|
+
expect(Result.isOk(mapped)).toBe(true);
|
|
160
|
+
if (Result.isOk(mapped)) {
|
|
161
|
+
expect(mapped.value).toBe(42);
|
|
162
|
+
}
|
|
163
|
+
expectType<typeof mapped, Result<number, string>>('~=');
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
test('should support curried form', () => {
|
|
167
|
+
const errorUppercase = Result.mapErr((e: string) => e.toUpperCase());
|
|
168
|
+
|
|
169
|
+
const errResult: Result<number, string> = Result.err('error');
|
|
170
|
+
const mapped = errorUppercase(errResult);
|
|
171
|
+
expect(Result.isErr(mapped)).toBe(true);
|
|
172
|
+
if (Result.isErr(mapped)) {
|
|
173
|
+
expect(mapped.value).toBe('ERROR');
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
const okResult: Result<number, string> = Result.ok(42);
|
|
177
|
+
const mappedOk = errorUppercase(okResult);
|
|
178
|
+
expect(Result.isOk(mappedOk)).toBe(true);
|
|
179
|
+
if (Result.isOk(mappedOk)) {
|
|
180
|
+
expect(mappedOk.value).toBe(42);
|
|
181
|
+
}
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
test('should work with pipe when curried', () => {
|
|
185
|
+
const errorUppercase = Result.mapErr((e: string) => e.toUpperCase());
|
|
186
|
+
const errorPrefix = Result.mapErr((e: string) => `ERROR: ${e}`);
|
|
187
|
+
|
|
188
|
+
const result = pipe(Result.err('failed'))
|
|
189
|
+
.map(errorUppercase)
|
|
190
|
+
.map(errorPrefix).value;
|
|
191
|
+
|
|
192
|
+
expect(Result.isErr(result)).toBe(true);
|
|
193
|
+
if (Result.isErr(result)) {
|
|
194
|
+
expect(result.value).toBe('ERROR: FAILED');
|
|
195
|
+
}
|
|
196
|
+
});
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
describe('unwrapThrow', () => {
|
|
200
|
+
test('unwraps Ok result', () => {
|
|
201
|
+
const result = Result.ok(42);
|
|
202
|
+
const value = Result.unwrapThrow(result);
|
|
203
|
+
expect(value).toBe(42);
|
|
204
|
+
expectType<typeof value, number>('<=');
|
|
205
|
+
});
|
|
206
|
+
|
|
207
|
+
test('throws on Err result', () => {
|
|
208
|
+
const result = Result.err('error message');
|
|
209
|
+
expect(() => Result.unwrapThrow(result)).toThrow('error message');
|
|
210
|
+
});
|
|
211
|
+
});
|
|
212
|
+
|
|
213
|
+
describe('unwrapOkOr', () => {
|
|
214
|
+
test('unwraps Ok result', () => {
|
|
215
|
+
const result = Result.ok(42);
|
|
216
|
+
const value = Result.unwrapOkOr(result, 0);
|
|
217
|
+
expect(value).toBe(42);
|
|
218
|
+
expectType<typeof value, number>('<=');
|
|
219
|
+
});
|
|
220
|
+
|
|
221
|
+
test('returns default for Err result', () => {
|
|
222
|
+
const result: Result<number, string> = Result.err('error');
|
|
223
|
+
const value = Result.unwrapOkOr(result, 0);
|
|
224
|
+
expect(value).toBe(0);
|
|
225
|
+
expectType<typeof value, number>('<=');
|
|
226
|
+
});
|
|
227
|
+
|
|
228
|
+
test('should support curried form', () => {
|
|
229
|
+
const unwrapWithDefault = Result.unwrapOkOr(42);
|
|
230
|
+
|
|
231
|
+
const okResult = Result.ok(100);
|
|
232
|
+
const successValue = unwrapWithDefault(okResult);
|
|
233
|
+
expect(successValue).toBe(100);
|
|
234
|
+
|
|
235
|
+
const errResult: Result<number, string> = Result.err('failed');
|
|
236
|
+
const defaultValue = unwrapWithDefault(errResult);
|
|
237
|
+
expect(defaultValue).toBe(42);
|
|
238
|
+
});
|
|
239
|
+
|
|
240
|
+
test('should work with pipe when curried', () => {
|
|
241
|
+
const unwrapWithDefault = Result.unwrapOkOr(0);
|
|
242
|
+
|
|
243
|
+
const successResult = pipe(Result.ok(200)).map(unwrapWithDefault).value;
|
|
244
|
+
expect(successResult).toBe(200);
|
|
245
|
+
|
|
246
|
+
const errorResult = pipe(Result.err('computation failed')).map(
|
|
247
|
+
unwrapWithDefault,
|
|
248
|
+
).value;
|
|
249
|
+
expect(errorResult).toBe(0);
|
|
250
|
+
});
|
|
251
|
+
});
|
|
252
|
+
|
|
253
|
+
describe('unwrapErr', () => {
|
|
254
|
+
test('unwraps Err result', () => {
|
|
255
|
+
const result: Result<number, string> = Result.err('error');
|
|
256
|
+
const value = Result.unwrapErr(result);
|
|
257
|
+
expect(value).toBe('error');
|
|
258
|
+
expectType<typeof value, string | undefined>('<=');
|
|
259
|
+
});
|
|
260
|
+
|
|
261
|
+
test('returns undefined for Ok result', () => {
|
|
262
|
+
const result: Result<number, string> = Result.ok(42);
|
|
263
|
+
// eslint-disable-next-line @typescript-eslint/no-confusing-void-expression
|
|
264
|
+
const value = Result.unwrapErr(result);
|
|
265
|
+
expect(value).toBeUndefined();
|
|
266
|
+
expectType<typeof value, string | undefined>('<=');
|
|
267
|
+
});
|
|
268
|
+
});
|
|
269
|
+
|
|
270
|
+
describe('fold', () => {
|
|
271
|
+
test('folds Ok result', () => {
|
|
272
|
+
const result = Result.ok(42);
|
|
273
|
+
const folded = Result.fold(
|
|
274
|
+
result,
|
|
275
|
+
(x) => x * 2,
|
|
276
|
+
() => 0,
|
|
277
|
+
);
|
|
278
|
+
expect(Result.isOk(folded)).toBe(true);
|
|
279
|
+
if (Result.isOk(folded)) {
|
|
280
|
+
expect(folded.value).toBe(84);
|
|
281
|
+
}
|
|
282
|
+
expectType<typeof folded, Result<number, number>>('=');
|
|
283
|
+
});
|
|
284
|
+
|
|
285
|
+
test('folds Err result', () => {
|
|
286
|
+
const result: Result<number, string> = Result.err('error');
|
|
287
|
+
const folded = Result.fold(
|
|
288
|
+
result,
|
|
289
|
+
(x) => x * 2,
|
|
290
|
+
(e) => e.length,
|
|
291
|
+
);
|
|
292
|
+
expect(Result.isErr(folded)).toBe(true);
|
|
293
|
+
if (Result.isErr(folded)) {
|
|
294
|
+
expect(folded.value).toBe(5); // length of 'error'
|
|
295
|
+
}
|
|
296
|
+
expectType<typeof folded, Result<number, number>>('=');
|
|
297
|
+
});
|
|
298
|
+
|
|
299
|
+
test('should support curried form', () => {
|
|
300
|
+
const folder = Result.fold(
|
|
301
|
+
(x: number) => x * 2,
|
|
302
|
+
(e: string) => e.length,
|
|
303
|
+
);
|
|
304
|
+
|
|
305
|
+
const okResult = Result.ok(42);
|
|
306
|
+
const foldedOk = folder(okResult);
|
|
307
|
+
expect(Result.isOk(foldedOk)).toBe(true);
|
|
308
|
+
if (Result.isOk(foldedOk)) {
|
|
309
|
+
expect(foldedOk.value).toBe(84);
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
const errResult: Result<number, string> = Result.err('error');
|
|
313
|
+
const foldedErr = folder(errResult);
|
|
314
|
+
expect(Result.isErr(foldedErr)).toBe(true);
|
|
315
|
+
if (Result.isErr(foldedErr)) {
|
|
316
|
+
expect(foldedErr.value).toBe(5);
|
|
317
|
+
}
|
|
318
|
+
});
|
|
319
|
+
|
|
320
|
+
test('should work with pipe when curried', () => {
|
|
321
|
+
const folder = Result.fold(
|
|
322
|
+
(x: number) => x * 2,
|
|
323
|
+
() => 0,
|
|
324
|
+
);
|
|
325
|
+
|
|
326
|
+
const result = pipe(Result.ok(21)).map(folder).value;
|
|
327
|
+
|
|
328
|
+
expect(Result.isOk(result)).toBe(true);
|
|
329
|
+
if (Result.isOk(result)) {
|
|
330
|
+
expect(result.value).toBe(42);
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
const errorResult = pipe(Result.err('error')).map(folder).value;
|
|
334
|
+
|
|
335
|
+
expect(Result.isErr(errorResult)).toBe(true);
|
|
336
|
+
if (Result.isErr(errorResult)) {
|
|
337
|
+
expect(errorResult.value).toBe(0);
|
|
338
|
+
}
|
|
339
|
+
});
|
|
340
|
+
});
|
|
341
|
+
|
|
342
|
+
describe('fromPromise', () => {
|
|
343
|
+
test('handles async functions that resolve', async () => {
|
|
344
|
+
const asyncFn = async (): Promise<number> =>
|
|
345
|
+
Promise.resolve().then(() => 42);
|
|
346
|
+
|
|
347
|
+
const result = await Result.fromPromise(asyncFn());
|
|
348
|
+
expect(Result.isOk(result)).toBe(true);
|
|
349
|
+
expect(Result.unwrapOk(result)).toBe(42);
|
|
350
|
+
});
|
|
351
|
+
|
|
352
|
+
test('handles async functions that reject', async () => {
|
|
353
|
+
const error = new Error('Async error');
|
|
354
|
+
const asyncFn = async (): Promise<number> =>
|
|
355
|
+
Promise.reject(error).then(() => 42);
|
|
356
|
+
|
|
357
|
+
const result = await Result.fromPromise(asyncFn());
|
|
358
|
+
expect(Result.isErr(result)).toBe(true);
|
|
359
|
+
expect(Result.unwrapErr(result)).toBe(error);
|
|
360
|
+
});
|
|
361
|
+
|
|
362
|
+
test('works with different promise types', async () => {
|
|
363
|
+
const stringPromise = Promise.resolve('hello');
|
|
364
|
+
const result = await Result.fromPromise(stringPromise);
|
|
365
|
+
|
|
366
|
+
expect(Result.unwrapOk(result)).toBe('hello');
|
|
367
|
+
expectType<typeof result, Result<string, unknown>>('=');
|
|
368
|
+
});
|
|
369
|
+
});
|
|
370
|
+
|
|
371
|
+
describe('flatMap', () => {
|
|
372
|
+
test('should chain operations that return Result', () => {
|
|
373
|
+
const divide = (a: number, b: number): Result<number, string> =>
|
|
374
|
+
b === 0 ? Result.err('Division by zero') : Result.ok(a / b);
|
|
375
|
+
|
|
376
|
+
const result = Result.flatMap(Result.ok(10), (x) => divide(x, 2));
|
|
377
|
+
expect(Result.unwrapOk(result)).toBe(5);
|
|
378
|
+
|
|
379
|
+
const error = Result.flatMap(Result.ok(10), (x) => divide(x, 0));
|
|
380
|
+
expect(Result.unwrapErr(error)).toBe('Division by zero');
|
|
381
|
+
});
|
|
382
|
+
|
|
383
|
+
test('should return Err if input is Err', () => {
|
|
384
|
+
const result = Result.flatMap(Result.err('initial error'), (_: never) =>
|
|
385
|
+
Result.ok(42),
|
|
386
|
+
);
|
|
387
|
+
expect(Result.unwrapErr(result)).toBe('initial error');
|
|
388
|
+
});
|
|
389
|
+
|
|
390
|
+
test('should support chaining multiple flatMaps', () => {
|
|
391
|
+
const parseNumber = (s: string): Result<number, string> => {
|
|
392
|
+
const n = Number(s);
|
|
393
|
+
return Number.isNaN(n) ? Result.err('Not a number') : Result.ok(n);
|
|
394
|
+
};
|
|
395
|
+
|
|
396
|
+
const divide = (a: number, b: number): Result<number, string> =>
|
|
397
|
+
b === 0 ? Result.err('Division by zero') : Result.ok(a / b);
|
|
398
|
+
|
|
399
|
+
const result = Result.flatMap(
|
|
400
|
+
Result.flatMap(parseNumber('100'), (x) => divide(x, 2)),
|
|
401
|
+
(x) => Result.ok(x + 10),
|
|
402
|
+
);
|
|
403
|
+
expect(Result.unwrapOk(result)).toBe(60);
|
|
404
|
+
});
|
|
405
|
+
|
|
406
|
+
test('should support curried form', () => {
|
|
407
|
+
const divide = (a: number, b: number): Result<number, string> =>
|
|
408
|
+
b === 0 ? Result.err('Division by zero') : Result.ok(a / b);
|
|
409
|
+
|
|
410
|
+
const divideBy2 = Result.flatMap((x: number) => divide(x, 2));
|
|
411
|
+
|
|
412
|
+
const okResult = Result.ok(10);
|
|
413
|
+
const result = divideBy2(okResult);
|
|
414
|
+
expect(Result.isOk(result)).toBe(true);
|
|
415
|
+
if (Result.isOk(result)) {
|
|
416
|
+
expect(result.value).toBe(5);
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
const divideByZero = Result.flatMap((x: number) => divide(x, 0));
|
|
420
|
+
const errorResult = divideByZero(Result.ok(10));
|
|
421
|
+
expect(Result.isErr(errorResult)).toBe(true);
|
|
422
|
+
if (Result.isErr(errorResult)) {
|
|
423
|
+
expect(errorResult.value).toBe('Division by zero');
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
const initialError = divideBy2(Result.err('initial error'));
|
|
427
|
+
expect(Result.isErr(initialError)).toBe(true);
|
|
428
|
+
if (Result.isErr(initialError)) {
|
|
429
|
+
expect(initialError.value).toBe('initial error');
|
|
430
|
+
}
|
|
431
|
+
});
|
|
432
|
+
|
|
433
|
+
test('should work with pipe when curried', () => {
|
|
434
|
+
const parseNumber = (s: string): Result<number, string> => {
|
|
435
|
+
const n = Number(s);
|
|
436
|
+
return Number.isNaN(n) ? Result.err('Not a number') : Result.ok(n);
|
|
437
|
+
};
|
|
438
|
+
|
|
439
|
+
const doubleIfPositive = (n: number): Result<number, string> =>
|
|
440
|
+
n > 0 ? Result.ok(n * 2) : Result.err('Not positive');
|
|
441
|
+
|
|
442
|
+
const parser = Result.flatMap(parseNumber);
|
|
443
|
+
const doubler = Result.flatMap(doubleIfPositive);
|
|
444
|
+
|
|
445
|
+
const result = pipe(Result.ok('42')).map(parser).map(doubler).value;
|
|
446
|
+
|
|
447
|
+
expect(Result.isOk(result)).toBe(true);
|
|
448
|
+
if (Result.isOk(result)) {
|
|
449
|
+
expect(result.value).toBe(84);
|
|
450
|
+
}
|
|
451
|
+
});
|
|
452
|
+
});
|
|
453
|
+
|
|
454
|
+
describe('swap', () => {
|
|
455
|
+
test('should swap Ok to Err', () => {
|
|
456
|
+
const okResult = Result.ok(42);
|
|
457
|
+
const swapped = Result.swap(okResult);
|
|
458
|
+
expect(Result.isErr(swapped)).toBe(true);
|
|
459
|
+
expect(Result.unwrapErr(swapped)).toBe(42);
|
|
460
|
+
});
|
|
461
|
+
|
|
462
|
+
test('should swap Err to Ok', () => {
|
|
463
|
+
const errResult = Result.err('error');
|
|
464
|
+
const swapped = Result.swap(errResult);
|
|
465
|
+
expect(Result.isOk(swapped)).toBe(true);
|
|
466
|
+
expect(Result.unwrapOk(swapped)).toBe('error');
|
|
467
|
+
});
|
|
468
|
+
});
|
|
469
|
+
|
|
470
|
+
describe('toOptional', () => {
|
|
471
|
+
test('should convert Ok to Some-like', () => {
|
|
472
|
+
const okResult = Result.ok(42);
|
|
473
|
+
const optional = Result.toOptional(okResult);
|
|
474
|
+
expect(Optional.isSome(optional)).toBe(true);
|
|
475
|
+
expect(Optional.unwrapThrow(optional)).toBe(42);
|
|
476
|
+
});
|
|
477
|
+
|
|
478
|
+
test('should convert Err to None-like', () => {
|
|
479
|
+
const errResult = Result.err('error');
|
|
480
|
+
const optional = Result.toOptional(errResult);
|
|
481
|
+
expect(Optional.isNone(optional)).toBe(true);
|
|
482
|
+
});
|
|
483
|
+
});
|
|
484
|
+
|
|
485
|
+
describe('unwrapErrThrow', () => {
|
|
486
|
+
test('should return error value for Err', () => {
|
|
487
|
+
const result = Result.err('error message');
|
|
488
|
+
expect(Result.unwrapErrThrow(result)).toBe('error message');
|
|
489
|
+
});
|
|
490
|
+
|
|
491
|
+
test('should throw for Ok', () => {
|
|
492
|
+
const result = Result.ok(42);
|
|
493
|
+
expect(() => Result.unwrapErrThrow(result)).toThrow(
|
|
494
|
+
'Expected Err but got Ok: 42',
|
|
495
|
+
);
|
|
496
|
+
});
|
|
497
|
+
|
|
498
|
+
test('should use custom toString function', () => {
|
|
499
|
+
const result = Result.ok({ id: 1, name: 'test' });
|
|
500
|
+
expect(() =>
|
|
501
|
+
Result.unwrapErrThrow(result, (obj) => `Object(id=${obj.id})`),
|
|
502
|
+
).toThrow('Expected Err but got Ok: Object(id=1)');
|
|
503
|
+
});
|
|
504
|
+
});
|
|
505
|
+
|
|
506
|
+
describe('unwrapErrOr', () => {
|
|
507
|
+
test('should return error value for Err result', () => {
|
|
508
|
+
const result = Result.err('error message');
|
|
509
|
+
const value = Result.unwrapErrOr(result, 'default');
|
|
510
|
+
expect(value).toBe('error message');
|
|
511
|
+
});
|
|
512
|
+
|
|
513
|
+
test('should return default value for Ok result', () => {
|
|
514
|
+
const result = Result.ok(42);
|
|
515
|
+
const value = Result.unwrapErrOr(result, 'default');
|
|
516
|
+
expect(value).toBe('default');
|
|
517
|
+
});
|
|
518
|
+
|
|
519
|
+
test('should support curried form', () => {
|
|
520
|
+
const unwrapErrorWithDefault = Result.unwrapErrOr('unknown error');
|
|
521
|
+
|
|
522
|
+
const errResult: Result<number, string> = Result.err('failed');
|
|
523
|
+
const errorValue = unwrapErrorWithDefault(errResult);
|
|
524
|
+
expect(errorValue).toBe('failed');
|
|
525
|
+
|
|
526
|
+
const okResult: Result<number, string> = Result.ok(42);
|
|
527
|
+
const defaultValue = unwrapErrorWithDefault(okResult);
|
|
528
|
+
expect(defaultValue).toBe('unknown error');
|
|
529
|
+
});
|
|
530
|
+
|
|
531
|
+
test('should work with pipe when curried', () => {
|
|
532
|
+
const unwrapErrorWithDefault = Result.unwrapErrOr('unknown error');
|
|
533
|
+
|
|
534
|
+
const errorResult = pipe(Result.err('network failure')).map(
|
|
535
|
+
unwrapErrorWithDefault,
|
|
536
|
+
).value;
|
|
537
|
+
expect(errorResult).toBe('network failure');
|
|
538
|
+
|
|
539
|
+
const okResult = pipe(Result.ok('success')).map(
|
|
540
|
+
unwrapErrorWithDefault,
|
|
541
|
+
).value;
|
|
542
|
+
expect(okResult).toBe('unknown error');
|
|
543
|
+
});
|
|
544
|
+
});
|
|
545
|
+
|
|
546
|
+
describe('expectToBe', () => {
|
|
547
|
+
test('should return value for Ok result', () => {
|
|
548
|
+
const result = Result.ok(42);
|
|
549
|
+
const value = Result.expectToBe(result, 'Expected valid number');
|
|
550
|
+
expect(value).toBe(42);
|
|
551
|
+
});
|
|
552
|
+
|
|
553
|
+
test('should throw custom error for Err result', () => {
|
|
554
|
+
const result = Result.err('failed');
|
|
555
|
+
expect(() => Result.expectToBe(result, 'Operation must succeed')).toThrow(
|
|
556
|
+
'Operation must succeed',
|
|
557
|
+
);
|
|
558
|
+
});
|
|
559
|
+
|
|
560
|
+
test('should support curried form', () => {
|
|
561
|
+
const mustBeOk = Result.expectToBe('Expected successful result');
|
|
562
|
+
|
|
563
|
+
const okResult = Result.ok('success');
|
|
564
|
+
const value = mustBeOk(okResult);
|
|
565
|
+
expect(value).toBe('success');
|
|
566
|
+
|
|
567
|
+
const errResult: Result<string, string> = Result.err('failed');
|
|
568
|
+
expect(() => mustBeOk(errResult)).toThrow('Expected successful result');
|
|
569
|
+
});
|
|
570
|
+
|
|
571
|
+
test('should work with pipe when curried', () => {
|
|
572
|
+
const mustBeOk = Result.expectToBe('Validation failed');
|
|
573
|
+
|
|
574
|
+
const successResult = pipe(Result.ok(100)).map(mustBeOk).value;
|
|
575
|
+
expect(successResult).toBe(100);
|
|
576
|
+
|
|
577
|
+
expect(
|
|
578
|
+
() => pipe(Result.err('validation error')).map(mustBeOk).value,
|
|
579
|
+
).toThrow('Validation failed');
|
|
580
|
+
});
|
|
581
|
+
});
|
|
582
|
+
|
|
583
|
+
describe('orElse', () => {
|
|
584
|
+
test('should return the first Result if it is Ok', () => {
|
|
585
|
+
const primary = Result.ok(42);
|
|
586
|
+
const fallback = Result.ok(100);
|
|
587
|
+
const result = Result.orElse(primary, fallback);
|
|
588
|
+
expect(Result.unwrapOk(result)).toBe(42);
|
|
589
|
+
});
|
|
590
|
+
|
|
591
|
+
test('should return the alternative if the first is Err', () => {
|
|
592
|
+
const primary = Result.err('error');
|
|
593
|
+
const fallback = Result.ok('default');
|
|
594
|
+
const result = Result.orElse(primary, fallback);
|
|
595
|
+
expect(Result.unwrapOk(result)).toBe('default');
|
|
596
|
+
});
|
|
597
|
+
|
|
598
|
+
test('should return Err if both are Err', () => {
|
|
599
|
+
const primary = Result.err('error1');
|
|
600
|
+
const fallback = Result.err('error2');
|
|
601
|
+
const result = Result.orElse(primary, fallback);
|
|
602
|
+
expect(Result.unwrapErr(result)).toBe('error2');
|
|
603
|
+
});
|
|
604
|
+
|
|
605
|
+
test('should support curried form', () => {
|
|
606
|
+
const fallbackTo = Result.orElse(Result.ok('fallback'));
|
|
607
|
+
|
|
608
|
+
const okResult = Result.ok('primary');
|
|
609
|
+
const result = fallbackTo(okResult);
|
|
610
|
+
expect(Result.isOk(result)).toBe(true);
|
|
611
|
+
if (Result.isOk(result)) {
|
|
612
|
+
expect(result.value).toBe('primary');
|
|
613
|
+
}
|
|
614
|
+
|
|
615
|
+
const errResult: Result<string, string> = Result.err('failed');
|
|
616
|
+
const fallbackResult = fallbackTo(errResult);
|
|
617
|
+
expect(Result.isOk(fallbackResult)).toBe(true);
|
|
618
|
+
if (Result.isOk(fallbackResult)) {
|
|
619
|
+
expect(fallbackResult.value).toBe('fallback');
|
|
620
|
+
}
|
|
621
|
+
});
|
|
622
|
+
|
|
623
|
+
test('should work with pipe when curried', () => {
|
|
624
|
+
const fallbackTo = Result.orElse(Result.ok('backup'));
|
|
625
|
+
|
|
626
|
+
const okResult = pipe(Result.ok('original')).map(fallbackTo).value;
|
|
627
|
+
expect(Result.isOk(okResult)).toBe(true);
|
|
628
|
+
if (Result.isOk(okResult)) {
|
|
629
|
+
expect(okResult.value).toBe('original');
|
|
630
|
+
}
|
|
631
|
+
|
|
632
|
+
const errResult = pipe(Result.err('network error')).map(fallbackTo).value;
|
|
633
|
+
expect(Result.isOk(errResult)).toBe(true);
|
|
634
|
+
if (Result.isOk(errResult)) {
|
|
635
|
+
expect(errResult.value).toBe('backup');
|
|
636
|
+
}
|
|
637
|
+
});
|
|
638
|
+
});
|
|
639
|
+
|
|
640
|
+
describe('zip', () => {
|
|
641
|
+
test('should combine two Ok values into a tuple', () => {
|
|
642
|
+
const a = Result.ok(1);
|
|
643
|
+
const b = Result.ok('hello');
|
|
644
|
+
const zipped = Result.zip(a, b);
|
|
645
|
+
expect(Result.unwrapOk(zipped)).toStrictEqual([1, 'hello']);
|
|
646
|
+
});
|
|
647
|
+
|
|
648
|
+
test('should return first Err if first is Err', () => {
|
|
649
|
+
const a = Result.err('error1');
|
|
650
|
+
const b = Result.ok('hello');
|
|
651
|
+
const zipped = Result.zip(a, b);
|
|
652
|
+
expect(Result.unwrapErr(zipped)).toBe('error1');
|
|
653
|
+
});
|
|
654
|
+
|
|
655
|
+
test('should return second Err if second is Err', () => {
|
|
656
|
+
const a = Result.ok(1);
|
|
657
|
+
const b = Result.err('error2');
|
|
658
|
+
const zipped = Result.zip(a, b);
|
|
659
|
+
expect(Result.unwrapErr(zipped)).toBe('error2');
|
|
660
|
+
});
|
|
661
|
+
|
|
662
|
+
test('should return first Err if both are Err', () => {
|
|
663
|
+
const a = Result.err('error1');
|
|
664
|
+
const b = Result.err('error2');
|
|
665
|
+
const zipped = Result.zip(a, b);
|
|
666
|
+
expect(Result.unwrapErr(zipped)).toBe('error1');
|
|
667
|
+
});
|
|
668
|
+
});
|
|
669
|
+
|
|
670
|
+
describe('fromThrowable', () => {
|
|
671
|
+
test('should return Ok when function succeeds', () => {
|
|
672
|
+
const result = Result.fromThrowable(() => 42);
|
|
673
|
+
expect(Result.isOk(result)).toBe(true);
|
|
674
|
+
expect(Result.unwrapOk(result)).toBe(42);
|
|
675
|
+
expectType<typeof result, Result<number, Error>>('<=');
|
|
676
|
+
});
|
|
677
|
+
|
|
678
|
+
test('should return Ok with object when function succeeds', () => {
|
|
679
|
+
const obj = { name: 'test', value: 123 };
|
|
680
|
+
const result = Result.fromThrowable(() => obj);
|
|
681
|
+
expect(Result.isOk(result)).toBe(true);
|
|
682
|
+
expect(Result.unwrapOk(result)).toStrictEqual(obj);
|
|
683
|
+
});
|
|
684
|
+
|
|
685
|
+
test('should return Err when function throws Error', () => {
|
|
686
|
+
const errorMessage = 'Something went wrong';
|
|
687
|
+
const result = Result.fromThrowable(() => {
|
|
688
|
+
throw new Error(errorMessage);
|
|
689
|
+
});
|
|
690
|
+
expect(Result.isErr(result)).toBe(true);
|
|
691
|
+
if (Result.isErr(result)) {
|
|
692
|
+
const error = result.value;
|
|
693
|
+
expect(error).toBeInstanceOf(Error);
|
|
694
|
+
expect(error.message).toBe(errorMessage);
|
|
695
|
+
}
|
|
696
|
+
});
|
|
697
|
+
|
|
698
|
+
test('should return Err when function throws string', () => {
|
|
699
|
+
const errorMessage = 'String error';
|
|
700
|
+
const result = Result.fromThrowable(() => {
|
|
701
|
+
// eslint-disable-next-line @typescript-eslint/only-throw-error
|
|
702
|
+
throw errorMessage;
|
|
703
|
+
});
|
|
704
|
+
expect(Result.isErr(result)).toBe(true);
|
|
705
|
+
if (Result.isErr(result)) {
|
|
706
|
+
const error = result.value;
|
|
707
|
+
expect(error).toBeInstanceOf(Error);
|
|
708
|
+
expect(error.message).toBe(errorMessage);
|
|
709
|
+
}
|
|
710
|
+
});
|
|
711
|
+
|
|
712
|
+
test('should return Err when function throws non-string primitive', () => {
|
|
713
|
+
const result = Result.fromThrowable(() => {
|
|
714
|
+
// eslint-disable-next-line @typescript-eslint/only-throw-error
|
|
715
|
+
throw 404;
|
|
716
|
+
});
|
|
717
|
+
expect(Result.isErr(result)).toBe(true);
|
|
718
|
+
if (Result.isErr(result)) {
|
|
719
|
+
const error = result.value;
|
|
720
|
+
expect(error).toBeInstanceOf(Error);
|
|
721
|
+
expect(error.message).toBe('404');
|
|
722
|
+
}
|
|
723
|
+
});
|
|
724
|
+
|
|
725
|
+
test('should work with JSON.parse', () => {
|
|
726
|
+
const validJson = '{"key": "value"}';
|
|
727
|
+
const invalidJson = '{invalid json}';
|
|
728
|
+
|
|
729
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
|
|
730
|
+
const validResult = Result.fromThrowable(() => JSON.parse(validJson));
|
|
731
|
+
expect(Result.isOk(validResult)).toBe(true);
|
|
732
|
+
expect(Result.unwrapOk(validResult)).toStrictEqual({ key: 'value' });
|
|
733
|
+
|
|
734
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
|
|
735
|
+
const invalidResult = Result.fromThrowable(() => JSON.parse(invalidJson));
|
|
736
|
+
expect(Result.isErr(invalidResult)).toBe(true);
|
|
737
|
+
if (Result.isErr(invalidResult)) {
|
|
738
|
+
const error = invalidResult.value;
|
|
739
|
+
expect(error).toBeInstanceOf(Error);
|
|
740
|
+
}
|
|
741
|
+
});
|
|
742
|
+
|
|
743
|
+
test('should work with array access', () => {
|
|
744
|
+
const arr = [1, 2, 3];
|
|
745
|
+
|
|
746
|
+
// This won't throw, but demonstrates the pattern
|
|
747
|
+
const result = Result.fromThrowable(() => {
|
|
748
|
+
const index = 5;
|
|
749
|
+
const value = arr[index];
|
|
750
|
+
if (value === undefined) {
|
|
751
|
+
throw new Error('Index out of bounds');
|
|
752
|
+
}
|
|
753
|
+
return value;
|
|
754
|
+
});
|
|
755
|
+
|
|
756
|
+
expect(Result.isErr(result)).toBe(true);
|
|
757
|
+
if (Result.isErr(result)) {
|
|
758
|
+
const error = result.value;
|
|
759
|
+
expect(error.message).toBe('Index out of bounds');
|
|
760
|
+
}
|
|
761
|
+
});
|
|
762
|
+
|
|
763
|
+
test('should preserve function return type', () => {
|
|
764
|
+
expectTypeOf(Result.fromThrowable(() => 'hello')).toEqualTypeOf<
|
|
765
|
+
Result<string, Error>
|
|
766
|
+
>();
|
|
767
|
+
|
|
768
|
+
expectTypeOf(Result.fromThrowable(() => 42)).toEqualTypeOf<
|
|
769
|
+
Result<number, Error>
|
|
770
|
+
>();
|
|
771
|
+
|
|
772
|
+
expectTypeOf(Result.fromThrowable(() => true)).toEqualTypeOf<
|
|
773
|
+
Result<boolean, Error>
|
|
774
|
+
>();
|
|
775
|
+
});
|
|
776
|
+
});
|
|
777
|
+
});
|