I'm using monocle-ts (https://github.com/gcanti/monocle-ts) library in my project. I have the following code
import {id, prop} from 'monocle-ts/lib/Lens'
import {pipe} from 'fp-ts/function'
type State = {a: string, b: string}
const stateLens = id<State>()
const aLens = pipe(stateLens, prop('a'))
^ this code works perfectly fine, type system will not allow me to pass string that is not either 'a' or 'b'. However if I'm trying to write the same code in other way:
const aLens = prop('a')(stateLens)
I'm getting an error: Argument of type 'string' is not assignable to parameter of type 'never'
Type definitions of prop
function looks like this:
declare const prop: <A, P extends keyof A>(prop: P) => <S>(sa: Lens<S, A>) => Lens<S, A[P]>
I'm guessing that by using pipe-style typescript is somehow able to infer all generic parameters which is not the case for regular prop(...)(...)
invocation
The alternative notation you tried is a two-step process that first creates a lambda function using
prop('a')
and then immediately invoking it with...(stateLens)
. Theprop()
function only receives a key name 'a', but cannot determine the object it belongs to as it only has the string parameter 'a' to work with. So, in the type definitions ofprop
the typeA
will be resolved tonever
because it's not assigned and cannot be inferred.I didn't test this, but you probably can do the same by manually passing along the type like
but this is exactly what
pipe
does as it receives theState
type from the its first parameter, and I think you can agree that in this case usingpipe
looks nicer.So, you are right,
pipe
is able to infer the correct type and pass it toprop
.