Skip to content

Commit 382a730

Browse files
committed
Add explicit VariantPattern name
1 parent b64b054 commit 382a730

File tree

2 files changed

+32
-26
lines changed

2 files changed

+32
-26
lines changed

src/variants.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,12 @@ import { Pattern } from './types/Pattern';
33

44
export type Variant<k, d = never> = Compute<{ tag: k; value: d }>;
55

6+
/**
7+
* VariantPatterns can be used to match a Variant in a
8+
* `match` expression.
9+
*/
10+
type VariantPattern<k, p> = { tag: k; value: p };
11+
612
type AnyVariant = Variant<string, unknown>;
713

814
type Narrow<variant extends AnyVariant, k extends variant['tag']> = Extract<
@@ -16,7 +22,7 @@ type Constructor<k, v> = [v] extends [never]
1622
? <t>(value: t) => Variant<k, t>
1723
: {
1824
(value: v): Variant<k, v>;
19-
<p extends Pattern<v>>(pattern: p): Variant<k, p>;
25+
<p extends Pattern<v>>(pattern: p): VariantPattern<k, p>;
2026
};
2127

2228
type Impl<variant extends AnyVariant> = {

tests/variants.test.ts

Lines changed: 25 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,31 @@ describe('Variants', () => {
7474
).toEqual(false);
7575
});
7676

77+
it('Variants with type parameters should work', () => {
78+
const toString = (maybeShape: Maybe<Shape>) =>
79+
match(maybeShape)
80+
.with(Nothing(), () => 'Nothing')
81+
.with(
82+
Just(Circle({ radius: select() })),
83+
(radius) => `Just Circle { radius: ${radius} }`
84+
)
85+
.with(
86+
Just(Square(select())),
87+
({ sideLength }) => `Just Square sideLength: ${sideLength}`
88+
)
89+
.with(
90+
Just(Rectangle(select())),
91+
({ x, y }) => `Just Rectangle { x: ${x}, y: ${y} }`
92+
)
93+
.with(Just(Blob(select())), (area) => `Just Blob { area: ${area} }`)
94+
.exhaustive();
95+
96+
expect(toString(Just(Circle({ radius: 20 })))).toEqual(
97+
`Just Circle { radius: 20 }`
98+
);
99+
expect(toString(Nothing())).toEqual(`Nothing`);
100+
});
101+
77102
it('should be possible to put a union type in a variant', () => {
78103
// with a normal union
79104

@@ -101,31 +126,6 @@ describe('Variants', () => {
101126
);
102127
});
103128

104-
it('Variants with type parameters should work', () => {
105-
const toString = (maybeShape: Maybe<Shape>) =>
106-
match(maybeShape)
107-
.with(Nothing(), () => 'Nothing')
108-
.with(
109-
Just(Circle({ radius: select() })),
110-
(radius) => `Just Circle { radius: ${radius} }`
111-
)
112-
.with(
113-
Just(Square(select())),
114-
({ sideLength }) => `Just Square sideLength: ${sideLength}`
115-
)
116-
.with(
117-
Just(Rectangle(select())),
118-
({ x, y }) => `Just Rectangle { x: ${x}, y: ${y} }`
119-
)
120-
.with(Just(Blob(select())), (area) => `Just Blob { area: ${area} }`)
121-
.exhaustive();
122-
123-
expect(toString(Just(Circle({ radius: 20 })))).toEqual(
124-
`Just Circle { radius: 20 }`
125-
);
126-
expect(toString(Nothing())).toEqual(`Nothing`);
127-
});
128-
129129
it('should be possible to create a variant with several type parameters', () => {
130130
// Result
131131
type Result<E, A> = Variant<'Success', A> | Variant<'Err', E>;

0 commit comments

Comments
 (0)