2

I want to use sequenceS function but it does not correctly infer left types. Let's consider the following code:

declare function validateEmail(
  email: string
): E.Either<EmailValidationError, Email>
declare function validateUsername(
  username: string
): E.Either<UsernameValidationError, Email>

function validateData(inputs: {
  email: string
  username: string
}) {
  return sequenceS(E.Apply)({
    email: validateEmail(inputs.email),
    username: validateUsername(inputs.username),
  })
}

I get a following error: Type 'UsernameValidationError' is not assignable to type 'EmailValidationError'.

I know I can fix it by specifying the types explicitly like so:

function validateData(inputs: {email: string; username: string}) {
  return sequenceS(E.Apply as apply.Apply2C<
    'Either', UsernameValidationError | EmailValidationError
  >)({
    email: validateEmail(inputs.email),
    username: validateUsername(inputs.username),
  })
}

But that does not seem practical especially with big objects created this way. I can also use dot notation but that still leaves me wandering if I am doing something wrong with this sequenceS use. Is there a way how to tell typescript to automatically infer the left types?

David Novák
  • 1,455
  • 2
  • 18
  • 30
  • 1
    It's probably easier to use Do notation with apS/apSW instead of sequenceS. See this comment here: https://github.com/gcanti/fp-ts/issues/1568#issuecomment-919974527 – cdimitroulas Jul 04 '23 at 07:08

1 Answers1

0

For how sequenceS is defined it expects values with fixed types on Left. For your use case you can use Do notation.

function validateData(inputs: {
  email: string
  username: string
}) {
  return pipe(
    validateEmail(inputs.email),
    E.bindTo('email'),
    E.apSW('username', validateUsername(inputs.username),
  )
}
Denis Frezzato
  • 957
  • 6
  • 15