unsplash / sum-types

Safe, ergonomic, non-generic sum types in TypeScript.
https://unsplash.github.io/sum-types/
MIT License
42 stars 2 forks source link

Nested constructor produces unhelpful function union #12

Closed samhh closed 3 years ago

samhh commented 3 years ago
type A = Member<'A1', string> | Member<'A2', number>
type B = Member<'B1', A>

const { B1 } = create<B>()
declare const x: A
B1(x)
Diagnostics:
1. Argument of type 'A' is not assignable to parameter of type 'never'.
  The intersection 'Member<"A1", string> & Member<"A2", number>' was reduced to 'never' because property '[tagKey]' has conflicting types in some constituents.
    Type 'Member<"A1", string>' is not assignable to type 'never'.
samhh commented 3 years ago

The type of B1:

// What it is
const B1: ((x: Member<"A1", string>) => B) | ((x:  Member<"A2", number>) => B)

// What it needs to be
const B1: (x: A) => B
samhh commented 3 years ago

The conditional type in Constructor is distributing over the union B. It can be solved by changing the condition from B extends undefined to [B] extends [undefined], per this comment.