From 734e6a6de7fd56b838e00a82490c6a82965e0125 Mon Sep 17 00:00:00 2001 From: Jason Kuhrt Date: Mon, 5 Sep 2022 15:49:23 -0400 Subject: [PATCH] fix(match): else handler gets records minus those data-matched Previously the `.else` handler in this case would statically receive `A|B|C`. Now it correctly only receives `B|C`. ```ts Alge.match(dataABC) .A(...) .else((data) => ...) ``` --- src/match.ts | 8 ++++++-- tests/match/match.spec.ts | 6 +++++- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/match.ts b/src/match.ts index d458d97..4e6eb52 100644 --- a/src/match.ts +++ b/src/match.ts @@ -13,7 +13,7 @@ Terminology: */ import { OmitTag } from './core/types.js' -import { inspect } from './lib/utils.js' +import { inspect, ObjectValues } from './lib/utils.js' import { SomeRecord } from './record/types/controller.js' import isMatch from 'lodash.ismatch' @@ -151,6 +151,10 @@ type PostMatcher Result } : { - else: (value: ThisResult| ((data: ADT) => ThisResult)) => Result|ThisResult + else: (value: ThisResult | ((data: ExcludeByTag) => ThisResult)) => Result | ThisResult } ) + +type ExcludeByTag = Record extends { _tag: Tag } + ? never + : Record diff --git a/tests/match/match.spec.ts b/tests/match/match.spec.ts index 1370a46..ee866f5 100644 --- a/tests/match/match.spec.ts +++ b/tests/match/match.spec.ts @@ -102,6 +102,10 @@ describe(`. (Data Matcher)`, () => { }) describe(`.else`, () => { + it('does not receive tag X when a data matcher for X has been set', () => { + const builder = Alge.match(a as ab).A(() => 1) + builder.else((data) => expectType(data)) + }) it(`not available if no matchers have been defined`, () => { const builder = Alge.match(ab) // @ts-expect-error Not available yet. @@ -119,7 +123,7 @@ describe(`.else`, () => { it(`is available if some but not all tag matchers have been defined`, () => { const builder = Alge.match(ab).A(() => 1 as const) expectType( - 0 as any as (value: ThisResult | ((data: ab) => ThisResult)) => 1 | ThisResult + 0 as any as (value: ThisResult | ((data: B) => ThisResult)) => 1 | ThisResult ) expect(builder.else).toBeDefined() })