Skip to content

Commit 06bc7c9

Browse files
committed
Add branch awareness and tests for the type of 'alt'
1 parent 6885efd commit 06bc7c9

File tree

2 files changed

+88
-4
lines changed

2 files changed

+88
-4
lines changed

index.d.ts

+32-4
Original file line numberDiff line numberDiff line change
@@ -86,10 +86,38 @@ export function after(duration: number): <R>(value: R) => Resolved<R>
8686
export function and<L, R>(left: FutureInstance<L, R>): (right: FutureInstance<L, any>) => FutureInstance<L, R>
8787

8888
/** Logical or for Futures. See https://github.com/fluture-js/Fluture#alt */
89-
export function alt<L, R>(left: FutureInstance<L, R>): (right: FutureInstance<L, R>) => FutureInstance<L, R>
90-
91-
/** Race two ConcurrentFutures. See https://github.com/fluture-js/Fluture#alt */
92-
export function alt<L, R>(left: ConcurrentFutureInstance<L, R>): (right: ConcurrentFutureInstance<L, R>) => ConcurrentFutureInstance<L, R>
89+
export const alt: {
90+
<F extends AnyFuture, S extends AnyFuture>(second: F extends Never ? S : never): (first: F) => Never
91+
<F extends AnyFuture, S extends AnyFuture>(second: F extends Rejected<unknown> ? S : never): (first: F) => S
92+
<F extends AnyFuture, S extends AnyFuture>(second: F extends Resolved<unknown> ? S : never): (first: F) => F
93+
94+
<L>(second: Rejected<L>): {
95+
(first: Never): Never
96+
(first: Rejected<any>): Rejected<L>
97+
<R>(first: Resolved<R>): Resolved<R>
98+
<R>(first: Uncertain<any, R>): Uncertain<L, R>
99+
}
100+
101+
<L, R>(second: Uncertain<L, R>): {
102+
<T>(first: Resolved<T>): Resolved<T>
103+
(first: Rejected<any>): Uncertain<L, R>
104+
(first: Uncertain<any, R>): Uncertain<L, R>
105+
}
106+
107+
(second: ConcurrentNever): <L, R>(first: ConcurrentUncertain<L, R>) => ConcurrentUncertain<L, R>
108+
109+
<L>(second: ConcurrentRejected<L>): {
110+
<R>(first: ConcurrentResolved<R>): ConcurrentUncertain<L, R>
111+
<R>(first: ConcurrentUncertain<L, R>): ConcurrentUncertain<L, R>
112+
}
113+
114+
<R>(second: ConcurrentResolved<R>): {
115+
<L>(first: ConcurrentRejected<L>): ConcurrentUncertain<L, R>
116+
<L>(first: ConcurrentUncertain<L, R>): ConcurrentUncertain<L, R>
117+
}
118+
119+
<L, R>(second: ConcurrentUncertain<L, R>): (first: ConcurrentUncertain<L, R>) => ConcurrentUncertain<L, R>
120+
}
93121

94122
/** Apply the function in the right Future to the value in the left Future. See https://github.com/fluture-js/Fluture#ap */
95123
export function ap<L, RA>(value: FutureInstance<L, RA>): <RB>(apply: FutureInstance<L, (value: RA) => RB>) => FutureInstance<L, RB>

test/types/alt.test-d.ts

+56
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
import {expectType, expectError} from 'tsd';
2+
3+
import * as fl from '../../index.js';
4+
5+
const fsn: fl.FutureInstance<string, number> = fl.resolve (42);
6+
const fns: fl.FutureInstance<number, string> = fl.resolve ('a');
7+
8+
// Standard usage on Future instances.
9+
expectType<fl.Never> (fl.alt (fl.never) (fl.never));
10+
expectType<fl.Never> (fl.alt (fl.reject ('a')) (fl.never));
11+
expectType<fl.Never> (fl.alt (fl.resolve ('a')) (fl.never));
12+
expectType<fl.Never> (fl.alt (fl.never) (fl.reject ('a')));
13+
expectType<fl.Resolved<string>> (fl.alt (fl.never) (fl.resolve ('a')));
14+
expectType<fl.Resolved<number>> (fl.alt (fl.reject ('a')) (fl.resolve (42)));
15+
expectType<fl.Resolved<number>> (fl.alt (fl.resolve (42)) (fl.reject ('a')));
16+
expectType<fl.Resolved<number>> (fl.alt (fl.resolve (42)) (fl.resolve (42)));
17+
expectType<fl.Rejected<number>> (fl.alt (fl.reject (42)) (fl.reject (42)));
18+
expectType<fl.Rejected<string>> (fl.alt (fl.reject ('a')) (fl.reject (42)));
19+
expectType<fl.Uncertain<string, number>> (fl.alt (fsn) (fsn));
20+
expectType<fl.Resolved<number>> (fl.alt (fl.resolve ('a')) (fl.resolve (42)));
21+
expectError (fl.alt (fsn) (fns));
22+
23+
const x = fl.alt (fl.never) (fl.never)
24+
25+
// Usage with pipe on Future instances (https://git.io/JLx3F).
26+
expectType<fl.Never> ((fl.never) .pipe (fl.alt (fl.never)));
27+
expectType<fl.Never> ((fl.never) .pipe (fl.alt (fl.reject ('a'))));
28+
expectType<fl.Never> ((fl.never) .pipe (fl.alt (fl.resolve ('a'))));
29+
expectType<fl.Never> ((fl.reject ('a')) .pipe (fl.alt (fl.never)));
30+
expectType<fl.Resolved<string>> ((fl.resolve ('a')) .pipe (fl.alt (fl.never)));
31+
expectType<fl.Resolved<number>> ((fl.resolve (42)) .pipe (fl.alt (fl.reject ('a'))));
32+
expectType<fl.Resolved<number>> ((fl.reject ('a')) .pipe (fl.alt (fl.resolve (42))));
33+
expectType<fl.Resolved<number>> ((fl.resolve (42)) .pipe (fl.alt (fl.resolve (42))));
34+
expectType<fl.Rejected<number>> ((fl.reject (42)) .pipe (fl.alt (fl.reject (42))));
35+
expectType<fl.Rejected<string>> ((fl.reject (42)) .pipe (fl.alt (fl.reject ('a'))));
36+
expectType<fl.Uncertain<string, number>> ((fsn) .pipe (fl.alt (fsn)));
37+
expectType<fl.Resolved<number>> ((fl.resolve (42)) .pipe (fl.alt (fl.resolve ('a'))));
38+
expectError ((fns) .pipe (fl.alt (fsn)));
39+
40+
const csn: fl.ConcurrentFutureInstance<string, number> = fl.Par (fl.resolve (42));
41+
const cns: fl.ConcurrentFutureInstance<number, string> = fl.Par (fl.resolve ('a'));
42+
43+
// Standard usage on ConcurrentFuture instances.
44+
expectType<fl.ConcurrentNever> (fl.alt (fl.Par (fl.never)) (fl.Par (fl.never)));
45+
expectType<fl.ConcurrentRejected<string>> (fl.alt (fl.Par (fl.reject ('a'))) (fl.Par (fl.never)));
46+
expectType<fl.ConcurrentResolved<string>> (fl.alt (fl.Par (fl.resolve ('a'))) (fl.Par (fl.never)));
47+
expectType<fl.ConcurrentRejected<string>> (fl.alt (fl.Par (fl.never)) (fl.Par (fl.reject ('a'))));
48+
expectType<fl.ConcurrentResolved<string>> (fl.alt (fl.Par (fl.never)) (fl.Par (fl.resolve ('a'))));
49+
expectType<fl.ConcurrentFutureInstance<string, number>> (fl.alt (fl.Par (fl.reject ('a'))) (fl.Par (fl.resolve (42))));
50+
expectType<fl.ConcurrentFutureInstance<string, number>> (fl.alt (fl.Par (fl.resolve (42))) (fl.Par (fl.reject ('a'))));
51+
expectType<fl.ConcurrentResolved<number>> (fl.alt (fl.Par (fl.resolve (42))) (fl.Par (fl.resolve (42))));
52+
expectType<fl.ConcurrentRejected<number>> (fl.alt (fl.Par (fl.reject (42))) (fl.Par (fl.reject (42))));
53+
expectType<fl.ConcurrentUncertain<string, number>> (fl.alt (csn) (csn));
54+
expectError (fl.alt (fl.Par (fl.resolve ('a'))) (fl.Par (fl.resolve (42))));
55+
expectError (fl.alt (fl.Par (fl.reject ('a'))) (fl.Par (fl.reject (42))));
56+
expectError (fl.alt (csn) (cns));

0 commit comments

Comments
 (0)