TypeScript Limitation with Type Narrowing in Matcher Patterns

I think this is a typescript limitation and not a match problem, but what I would need to make this work?
class A extends Schema.TaggedClass<A>()("a", {}) {}
class B extends Schema.TaggedClass<B>()("b", {}) {}

type AB = A | B

const matcher = Match.type<{ start: AB | null; end: AB | null }>().pipe(
  Match.when({ start: null, end: null }, () => Effect.fail("")),
  Match.when(
    { start: Match.instanceOf(A), end: Match.instanceOf(A) },
    ({ start, end }) => Effect.succeed([start, end] as const)
  ),
  Match.when(
    { start: Match.instanceOf(B), end: Match.instanceOf(B) },
    ({ start, end }) => Effect.succeed([start, end] as const)
  ),
  Match.orElse(() => Effect.fail("Unsupported case"))
)

yield* matcher({ start: A.make(), end: A.make() }).pipe(
    Effect.tap(([a, b]) => {
      console.log({ a, b })
      //            ^?
      if (a._tag == "a") {
        console.log("b should be taggged a", { b, a })
        //                                     ^? { _tag: 'a'} | { _tag: 'b' }
      }
    })
  )

Here is a playground link: https://effect.website/play#16674fde6fc6
Was this page helpful?