#1705·fp-ts

Branching `if` statement in `Either.chainW` doesn't union properly

Author: atomanyihCreated Apr 28, 2022Updated Oct 11, 2024

Bug report

Current Behavior

Note: example has been replaced with a more representative case

typescript
type StoreError = {
  type: 'storeError';
  excuse: string;
};

type Hotdog = {
  type: 'hotdog';
  length: 'small' | 'medium' | 'large';
  name: string;
};

const getHotdog = (length: Hotdog['length']): E.Either<StoreError, Hotdog> => {
  return E.of({
    type: 'hotdog',
    length,
    name: 'Cindy',
  })
}

type Sausage = {
  type: 'sausage';
  length: 'small' | 'medium' | 'large';
  name: string;
};

const getSausage = (length: Sausage['length']): E.Either<StoreError, Sausage> => {
  return E.of({
    type: 'sausage',
    length,
    name: 'Addison',
  })
}

function getMediumHotdogOrSausage(type: 'hotdog' | 'sausage') {
  return pipe(
    E.of(type),
    E.chainW((type) => {
// TS2345: Argument of type '(type: "hotdog" | "sausage") => Left<StoreError> | Right<Hotdog> | Right<Sausage>' is not assignable to parameter of type '(a: "hotdog" | "sausage") => Either<StoreError, Hotdog>'.
//   Type 'Left<StoreError> | Right<Hotdog> | Right<Sausage>' is not assignable to type 'Either<StoreError, Hotdog>'.
//     Type 'Right<Sausage>' is not assignable to type 'Either<StoreError, Hotdog>'.
//       Type 'Right<Sausage>' is not assignable to type 'Right<Hotdog>'.
//         Type 'Sausage' is not assignable to type 'Hotdog'.
//           Types of property 'type' are incompatible.
//             Type '"sausage"' is not assignable to type '"hotdog"'.
      if (type === 'hotdog') {
        return getHotdog('medium');
      }

      return getSausage('small');
    }),
  );
}

Expected behavior

I would expect this to pass type-check and result in a type E.Either<StoreError, Sausage | Hotdog>.

Is there a better way to represent a branch like this?

Your environment

Which versions of fp-ts are affected by this issue? Did this work in previous versions of fp-ts?

Software Version(s)
fp-ts 2.11.8
TypeScript 4.5.5