DenisFrezzato / hyper-ts

Type safe middleware architecture for HTTP servers
https://denisfrezzato.github.io/hyper-ts/
MIT License
391 stars 18 forks source link

Do notation does not work as expected due to invalid transition from unknown to any other state #62

Closed mlegenhausen closed 2 years ago

mlegenhausen commented 2 years ago

Reproduceable example

import * as RH from 'hyper-ts/lib/ReaderMiddleware'

pipe(RH.Do, RH.apS('foo', RH.right<unknown, H.StatusOpen, never, string>('bar')))

You can replace apS with apSW, iapS or iapSW with the same type error.

Argument of type 'ReaderMiddleware<unknown, unknown, unknown, never, {}>' is not assignable to parameter of type 'ReaderMiddleware<unknown, StatusOpen, StatusOpen, never, {}>'.
  Type 'unknown' is not assignable to type 'StatusOpen'.ts(2345)

You can work around that issue by first binding via RH.bindTo and then add additional values via apS etc.

A possible solution would be to add generic parameter to Do to allow the setting of a initial type but maybe there is a more elegant solution.

export const Do: <I = unknown>() => ReaderMiddleware<unknown, I, I, never, {}>
DenisFrezzato commented 2 years ago

Do from Middleware suffers from the same problem too.

add generic parameter to Do

Yes, that would do the trick, but it's rather ugly, I would prefer going with bindTo.

The phantom type is set by a computation, which is always placed after Do, so TypeScript can't ever infer it successfully. I can't find better solutions. What if we deprecate Do in favour of just bindTo?

mlegenhausen commented 2 years ago

With a useful comment for the bindTo solution I think this sound like the best solution.