Closed
Description
I'm trying to work on TS typings for FP lib Ramda.
Several users have reported issues that came down to similar inference issues triggered in the presence of composition/currying involving functions containing generics.
Since FP encourages composing point-free functions (the majority of which use generics for type inference), what breaks here aren't so much edge cases, but idiomatic usage.
TypeScript Version: nightly (2.2.0-dev.20161211
)
Code (can paste into the TS playground):
declare function inc(n: number): number; // +1
declare function identity<T>(a: T): T;
declare function compose<V0, T1>(fn0: (x0: V0) => T1): (x0: V0) => T1;
declare function compose<V0, T1, T2>(fn1: (x: T1) => T2, fn0: (x: V0) => T1): (x: V0) => T2;
declare function pipe <V0, T1>(fn0: (x0: V0) => T1): (x0: V0) => T1; // arity 1: same as compose
declare function pipe <V0, T1, T2>(fn0: (x: V0) => T1, fn1: (x: T1) => T2): (x: V0) => T2; // arity 2: params swapped
// don't use generics if it can't resolve them right away:
compose(identity) // generics lost, now {} => {}
pipe (identity) // ditto
// argument order apparently matters too:
pipe (inc, identity); // ok, number -> number
compose(identity, inc); // nope, number => {}
// also no reasoning backward:
compose(inc, identity); // {} => number
pipe (identity, inc); // {} => number
Expected behavior:
identity
survives compositionidentity
not killing the type signature when composing withinc
Actual behavior:
- Things break as soon as TS gets a generic it can't immediately resolve (as opposed to keeping them intact).
- Even the same thing using different param order breaks for some reason.