Skip to content

Commit 13d9c5a

Browse files
committed
feat: add errorUnion to expand error types
1 parent f9d0861 commit 13d9c5a

File tree

2 files changed

+72
-44
lines changed

2 files changed

+72
-44
lines changed

docs/task-instance.md

+66-44
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,15 @@ Cancels a task, meaning it will never complete.
1010
{% tab title="Usage" %}
1111

1212
```typescript
13-
const task = Task.of(5).cancel();
13+
const task = Task.of(5).cancel()
1414
```
1515

1616
{% endtab %}
1717

1818
{% tab title="Type Definition" %}
1919

2020
```typescript
21-
type cancel = () => void;
21+
type cancel = () => void
2222
```
2323
2424
{% endtab %}
@@ -32,15 +32,15 @@ Given a task, when it has _succeeded_, pass the value through a mapping function
3232
{% tab title="Usage" %}
3333
3434
```typescript
35-
const task: Task<unknown, number> = Task.of(5).map(number => number * 2);
35+
const task: Task<unknown, number> = Task.of(5).map(number => number * 2)
3636
```
3737

3838
{% endtab %}
3939

4040
{% tab title="Type Definition" %}
4141

4242
```typescript
43-
type map = <S2>(fn: (result: S) => S2) => Task<E, S2>;
43+
type map = <S2>(fn: (result: S) => S2) => Task<E, S2>
4444
```
4545
4646
{% endtab %}
@@ -54,15 +54,39 @@ Given a task, when it has _failed_, pass the error through a mapping function to
5454
{% tab title="Usage" %}
5555
5656
```typescript
57-
const task: Task<unknown, number> = Task.fail(5).mapError(number => number * 2);
57+
const task: Task<unknown, number> = Task.fail(5).mapError(number => number * 2)
5858
```
5959

6060
{% endtab %}
6161

6262
{% tab title="Type Definition" %}
6363

6464
```typescript
65-
type mapError = <E2>(fn: (error: E) => E2) => Task<E2, S>;
65+
type mapError = <E2>(fn: (error: E) => E2) => Task<E2, S>
66+
```
67+
68+
{% endtab %}
69+
{% endtabs %}
70+
71+
## errorUnion
72+
73+
Expand the error types of a task. Purely a TypeScript type system modification.
74+
75+
{% tabs %}
76+
{% tab title="Usage" %}
77+
78+
```typescript
79+
const task: Task<unknown | AnotherErrorPossibility, number> = Task.fail(
80+
5
81+
).errorUnion<AnotherErrorPossibility>()
82+
```
83+
84+
{% endtab %}
85+
86+
{% tab title="Type Definition" %}
87+
88+
```typescript
89+
type errorUnion = <E2>() => Task<E | E2, S>
6690
```
6791
6892
{% endtab %}
@@ -79,7 +103,7 @@ Given a task, provide mapping functions for both the success and fail states. Re
79103
const task: Task<Error, number> = Task.of(5).mapBoth(
80104
() => new Error("Surprising Error"),
81105
number => number * 2
82-
);
106+
)
83107
```
84108

85109
{% endtab %}
@@ -90,7 +114,7 @@ const task: Task<Error, number> = Task.of(5).mapBoth(
90114
type mapBoth = <E2, S2>(
91115
handleError: (error: E) => E2,
92116
handleSuccess: (success: S) => S2
93-
) => Task<E2, S2>;
117+
) => Task<E2, S2>
94118
```
95119
96120
{% endtab %}
@@ -108,15 +132,15 @@ In general, users have difficulty understanding the difference between `chain` a
108132
```typescript
109133
const task: Task<unknown, number> = Task.of(5).chain(number =>
110134
Task.of(number * 2)
111-
);
135+
)
112136
```
113137

114138
{% endtab %}
115139

116140
{% tab title="Type Definition" %}
117141

118142
```typescript
119-
type chain = <S2>(fn: (result: S) => Task<E, S2> | Promise<S2>) => Task<E, S2>;
143+
type chain = <S2>(fn: (result: S) => Task<E, S2> | Promise<S2>) => Task<E, S2>
120144
```
121145
122146
{% endtab %}
@@ -130,15 +154,15 @@ Given a task, wait some number of milliseconds to forward the successful value.
130154
{% tab title="Usage" %}
131155
132156
```typescript
133-
const task: Task<unknown, number> = Task.of(5).wait(2000);
157+
const task: Task<unknown, number> = Task.of(5).wait(2000)
134158
```
135159

136160
{% endtab %}
137161

138162
{% tab title="Type Definition" %}
139163

140164
```typescript
141-
type wait = (ms: number) => Task<E, S>;
165+
type wait = (ms: number) => Task<E, S>
142166
```
143167
144168
{% endtab %}
@@ -154,15 +178,15 @@ Given a failing task, wait some number of seconds and attempt to retry it. Usefu
154178
```typescript
155179
const task: Task<unknown, Response> = Task.fromLazyPromise(() =>
156180
fetch(URL)
157-
).retryIn(2000);
181+
).retryIn(2000)
158182
```
159183

160184
{% endtab %}
161185

162186
{% tab title="Type Definition" %}
163187

164188
```typescript
165-
type retryIn = (ms: number) => Task<E, S>;
189+
type retryIn = (ms: number) => Task<E, S>
166190
```
167191
168192
{% endtab %}
@@ -178,15 +202,15 @@ Given a task, continue to retry it some number of times. The time between each a
178202
```typescript
179203
const task: Task<unknown, Response> = Task.fromLazyPromise(() =>
180204
fetch(URL)
181-
).retryWithExponentialBackoff(2000, 5);
205+
).retryWithExponentialBackoff(2000, 5)
182206
```
183207

184208
{% endtab %}
185209

186210
{% tab title="Type Definition" %}
187211

188212
```typescript
189-
type retryWithExponentialBackoff = (ms: number, times: number) => Task<E, S>;
213+
type retryWithExponentialBackoff = (ms: number, times: number) => Task<E, S>
190214
```
191215
192216
{% endtab %}
@@ -200,15 +224,15 @@ Given a task which succeeds with another task, flatten into a single task which
200224
{% tab title="Usage" %}
201225
202226
```typescript
203-
const task: Task<unknown, number> = Task.of(Task.of(5)).flatten();
227+
const task: Task<unknown, number> = Task.of(Task.of(5)).flatten()
204228
```
205229

206230
{% endtab %}
207231

208232
{% tab title="Type Definition" %}
209233

210234
```typescript
211-
type flatten = <S2>(this: Task<E, Task<E, S2>>) => Task<E, S2>;
235+
type flatten = <S2>(this: Task<E, Task<E, S2>>) => Task<E, S2>
212236
```
213237
214238
{% endtab %}
@@ -224,7 +248,7 @@ Given a task that fails, a function can be called to attempt a recovery. This is
224248
```typescript
225249
const task: Task<string, string> = Task.fail("Error").orElse(() =>
226250
Task.of("Success")
227-
);
251+
)
228252
```
229253

230254
{% endtab %}
@@ -234,7 +258,7 @@ const task: Task<string, string> = Task.fail("Error").orElse(() =>
234258
```typescript
235259
type orElse = <S2>(
236260
fn: (error: E) => Task<E, S | S2> | Promise<S | S2>
237-
) => Task<E, S | S2>;
261+
) => Task<E, S | S2>
238262
```
239263
240264
{% endtab %}
@@ -251,7 +275,7 @@ Given a task, provide a function to convert each of the success or error states
251275
const task: Task<unknown, JSX> = Task.fromPromise(fetch(URL)).fold(
252276
() => <h1>Error</h1>,
253277
data => <h1>Worked: ${data}</h1>
254-
);
278+
)
255279
```
256280

257281
{% endtab %}
@@ -262,7 +286,7 @@ const task: Task<unknown, JSX> = Task.fromPromise(fetch(URL)).fold(
262286
type fold = <R>(
263287
handleError: (error: E) => R,
264288
handleSuccess: (success: S) => R
265-
) => Task<unknown, R>;
289+
) => Task<unknown, R>
266290
```
267291
268292
{% endtab %}
@@ -278,15 +302,15 @@ Given a task, pass the success value to the tap (like tapping a tree or process)
278302
```typescript
279303
const task: Task<unknown, number> = Task.of(5).tap(num =>
280304
console.log("Got", num)
281-
);
305+
)
282306
```
283307

284308
{% endtab %}
285309

286310
{% tab title="Type Definition" %}
287311

288312
```typescript
289-
type tap = (fn: (result: S) => void) => Task<E, S>;
313+
type tap = (fn: (result: S) => void) => Task<E, S>
290314
```
291315
292316
{% endtab %}
@@ -302,17 +326,15 @@ Given a task, pass the success value to the tap (like tapping a tree or process)
302326
```typescript
303327
const task: Task<unknown, number> = Task.of(5).tap(num =>
304328
console.log("Got", num)
305-
);
329+
)
306330
```
307331

308332
{% endtab %}
309333

310334
{% tab title="Type Definition" %}
311335

312336
```typescript
313-
type tapChain = <S2>(
314-
fn: (result: S) => Task<E, S2> | Promise<S2>
315-
) => Task<E, S>;
337+
type tapChain = <S2>(fn: (result: S) => Task<E, S2> | Promise<S2>) => Task<E, S>
316338
```
317339
318340
{% endtab %}
@@ -344,7 +366,7 @@ for (let i = 0; i < 5, i++) {
344366
{% tab title="Type Definition" %}
345367

346368
```typescript
347-
type onlyOnce = () => Task<E, S>;
369+
type onlyOnce = () => Task<E, S>
348370
```
349371
350372
{% endtab %}
@@ -359,15 +381,15 @@ Like `onlyOnce`, but provides a function which can arbitrarily check whether the
359381
360382
```typescript
361383
// Succeed until some unknown date.
362-
const task: Task<unknown, number> = Task.of(5).succeedIf(() => Date.now() < x);
384+
const task: Task<unknown, number> = Task.of(5).succeedIf(() => Date.now() < x)
363385
```
364386

365387
{% endtab %}
366388

367389
{% tab title="Type Definition" %}
368390

369391
```typescript
370-
type succeedIf = (fn: () => S | undefined) => Task<E, S>;
392+
type succeedIf = (fn: () => S | undefined) => Task<E, S>
371393
```
372394
373395
{% endtab %}
@@ -381,15 +403,15 @@ Converts a task to a Promise. Useful for integrating with other libraries.
381403
{% tab title="Usage" %}
382404
383405
```typescript
384-
const promise: Promise<number> = Task.of(5).toPromise();
406+
const promise: Promise<number> = Task.of(5).toPromise()
385407
```
386408

387409
{% endtab %}
388410

389411
{% tab title="Type Definition" %}
390412

391413
```typescript
392-
type toPromise = () => Promise<S>;
414+
type toPromise = () => Promise<S>
393415
```
394416
395417
{% endtab %}
@@ -403,16 +425,16 @@ Swaps the error and success values so the old error message in the new success a
403425
{% tab title="Usage" %}
404426
405427
```typescript
406-
const task: Task<unknown, number> = Task.of(5);
407-
const swapped: Task<number, unknown> = task.swap();
428+
const task: Task<unknown, number> = Task.of(5)
429+
const swapped: Task<number, unknown> = task.swap()
408430
```
409431

410432
{% endtab %}
411433

412434
{% tab title="Type Definition" %}
413435

414436
```typescript
415-
type swap = () => Task<S, E>;
437+
type swap = () => Task<S, E>
416438
```
417439
418440
{% endtab %}
@@ -426,15 +448,15 @@ Given a successful Task, throw away the result and continue the chain with a new
426448
{% tab title="Usage" %}
427449
428450
```typescript
429-
const task: Task<unknown, string> = Task.of(5).forward(() => "Hello");
451+
const task: Task<unknown, string> = Task.of(5).forward(() => "Hello")
430452
```
431453

432454
{% endtab %}
433455

434456
{% tab title="Type Definition" %}
435457

436458
```typescript
437-
type forward = <S2>(value: S2) => Task<E, S2>;
459+
type forward = <S2>(value: S2) => Task<E, S2>
438460
```
439461
440462
{% endtab %}
@@ -448,15 +470,15 @@ Given a successful Task, join it before an additional value. Useful for threadin
448470
{% tab title="Usage" %}
449471
450472
```typescript
451-
const task: Task<unknown, [number, number]> = Task.of(5).append(10);
473+
const task: Task<unknown, [number, number]> = Task.of(5).append(10)
452474
```
453475

454476
{% endtab %}
455477

456478
{% tab title="Type Definition" %}
457479

458480
```typescript
459-
type append = <S2>(this: Task<E, S>, value: S2) => Task<E, [S, S2]>;
481+
type append = <S2>(this: Task<E, S>, value: S2) => Task<E, [S, S2]>
460482
```
461483
462484
{% endtab %}
@@ -470,15 +492,15 @@ Given a successful Task, join it after an additional value. Useful for threading
470492
{% tab title="Usage" %}
471493
472494
```typescript
473-
const task: Task<unknown, [number, number]> = Task.of(5).prepend(10);
495+
const task: Task<unknown, [number, number]> = Task.of(5).prepend(10)
474496
```
475497

476498
{% endtab %}
477499

478500
{% tab title="Type Definition" %}
479501

480502
```typescript
481-
type prepend = <S2>(this: Task<E, S>, value: S2) => Task<E, [S2, S]>;
503+
type prepend = <S2>(this: Task<E, S>, value: S2) => Task<E, [S2, S]>
482504
```
483505
484506
{% endtab %}
@@ -499,7 +521,7 @@ Also allows the definition of the mapping function to be asychronous because it
499521
const task: Task<unknown, number> = Task.of((a, b, c) => a + b + c)
500522
.ap(succeed(10)) // a
501523
.ap(succeed(50)) // b
502-
.ap(succeed(100)); // c
524+
.ap(succeed(100)) // c
503525
```
504526

505527
{% endtab %}
@@ -509,7 +531,7 @@ const task: Task<unknown, number> = Task.of((a, b, c) => a + b + c)
509531
```typescript
510532
type ap = <E2, S2, S3 = S extends (arg: S2) => any ? ReturnType<S> : never>(
511533
taskOrPromise: Task<E | E2, S2> | Promise<S2>
512-
) => Task<E | E2, S3>;
534+
) => Task<E | E2, S3>
513535
```
514536
515537
{% endtab %}

0 commit comments

Comments
 (0)