I've been bashing my head trying to create some sort of typed pipe for a while, with a syntax matching Elixirs, to avoid having to create curried functions all the time. The farthest I've gotten is that I achieve typing, so long as the function isn't generic. So this works:
const plus = (a: number, b: number) => a + b;
pipe(5)
.thru(plus, 3) // Pipe(8)
// ^---- this is inferred as `number`
But this doesn't function plus<T extends string|number>(a: T, b: T) {/* ... */}
pipe("five")
.thru(plus, "three") // Pipe("fivethree")
// ^--- this isnt inferred or narrowed,becoms `unknown` iirc