Just for kicks, I started tinkering with creating a Scala-inspired underscore in typescript. I aim to simplify writing code by replacing .map(x => x.myProp)
with just .map(_.myProp)
. The logic behind this is quite simple using Proxies, but the challenge lies in typing.
type Rec<T extends object, K extends keyof T> = T[K]
export const _ = new Proxy<
Record<string, <T extends object, K extends keyof T>(o: T) => Rec<T, K>>
>(
{},
{
get(target: any, p: string) {
return <T extends object, K extends typeof p & keyof T>(obj: T) => obj[p as K] as Rec<T, K>
}
}
)
This setup allows me to correctly pass the type through map in the subsequent chain, but I struggle to narrow down the myProp type:
https://i.sstatic.net/xDqFw.png
And that's where I hit a roadblock. I thought of potentially typing the Proxy with <any extends infer R ? R: never>, however, then the R cannot be used to refine the property in the get handler.
Any suggestions?
Edit:
Included a playground example
In the second identity map x
turns out to be string | number
instead of 'string'. When changing the first map to _.id
, x should only be number