From 382a7306c458b9b5b36fc0bffac3d6ae863a3c8c Mon Sep 17 00:00:00 2001 From: gvergnaud Date: Sun, 5 Sep 2021 13:31:10 +0200 Subject: [PATCH] Add explicit VariantPattern name --- src/variants.ts | 8 ++++++- tests/variants.test.ts | 50 +++++++++++++++++++++--------------------- 2 files changed, 32 insertions(+), 26 deletions(-) diff --git a/src/variants.ts b/src/variants.ts index 4d1cfd6d..074a2516 100644 --- a/src/variants.ts +++ b/src/variants.ts @@ -3,6 +3,12 @@ import { Pattern } from './types/Pattern'; export type Variant = Compute<{ tag: k; value: d }>; +/** + * VariantPatterns can be used to match a Variant in a + * `match` expression. + */ +type VariantPattern = { tag: k; value: p }; + type AnyVariant = Variant; type Narrow = Extract< @@ -16,7 +22,7 @@ type Constructor = [v] extends [never] ? (value: t) => Variant : { (value: v): Variant; -

>(pattern: p): Variant; +

>(pattern: p): VariantPattern; }; type Impl = { diff --git a/tests/variants.test.ts b/tests/variants.test.ts index 446d7e48..0e9675c7 100644 --- a/tests/variants.test.ts +++ b/tests/variants.test.ts @@ -74,6 +74,31 @@ describe('Variants', () => { ).toEqual(false); }); + it('Variants with type parameters should work', () => { + const toString = (maybeShape: Maybe) => + match(maybeShape) + .with(Nothing(), () => 'Nothing') + .with( + Just(Circle({ radius: select() })), + (radius) => `Just Circle { radius: ${radius} }` + ) + .with( + Just(Square(select())), + ({ sideLength }) => `Just Square sideLength: ${sideLength}` + ) + .with( + Just(Rectangle(select())), + ({ x, y }) => `Just Rectangle { x: ${x}, y: ${y} }` + ) + .with(Just(Blob(select())), (area) => `Just Blob { area: ${area} }`) + .exhaustive(); + + expect(toString(Just(Circle({ radius: 20 })))).toEqual( + `Just Circle { radius: 20 }` + ); + expect(toString(Nothing())).toEqual(`Nothing`); + }); + it('should be possible to put a union type in a variant', () => { // with a normal union @@ -101,31 +126,6 @@ describe('Variants', () => { ); }); - it('Variants with type parameters should work', () => { - const toString = (maybeShape: Maybe) => - match(maybeShape) - .with(Nothing(), () => 'Nothing') - .with( - Just(Circle({ radius: select() })), - (radius) => `Just Circle { radius: ${radius} }` - ) - .with( - Just(Square(select())), - ({ sideLength }) => `Just Square sideLength: ${sideLength}` - ) - .with( - Just(Rectangle(select())), - ({ x, y }) => `Just Rectangle { x: ${x}, y: ${y} }` - ) - .with(Just(Blob(select())), (area) => `Just Blob { area: ${area} }`) - .exhaustive(); - - expect(toString(Just(Circle({ radius: 20 })))).toEqual( - `Just Circle { radius: 20 }` - ); - expect(toString(Nothing())).toEqual(`Nothing`); - }); - it('should be possible to create a variant with several type parameters', () => { // Result type Result = Variant<'Success', A> | Variant<'Err', E>;