-
-
Notifications
You must be signed in to change notification settings - Fork 146
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.
Already on GitHub? Sign in to your account
Curry cannot infer generic type parameters correctly #207
Comments
It's a ts limitation that we cannot overcome yet. It comes from the simple fact that: type test0 = Parameters<<A, B>(a: A, b: B) => A> // [a: unknown, b: unknown] |
I will reopen this case as soon as it's fixable |
However, it could be possible to write a more type safe curry, but we'll have to say goodbye to the placeholder feature: declare function curry<R, A, B>(fn: (a: A, b: B) => R):
(a: A) => (b: B) => R |
Unfortunately, things like this don't work either. As soon as you have more than one overload, ts makes the generic interface CurriedFunction1<T1, R> {
(): CurriedFunction1<T1, R>;
(t1: T1): R;
}
interface CurriedFunction2<T1, T2, R> {
(): CurriedFunction2<T1, T2, R>;
(t1: T1): CurriedFunction1<T2, R>;
(t1: T1, t2: T2): R;
}
interface CurriedFunction3<T1, T2, T3, R> {
(): CurriedFunction3<T1, T2, T3, R>;
(t1: T1): CurriedFunction2<T2, T3, R>;
(t1: T1, t2: T2): CurriedFunction1<T3, R>;
(t1: T1, t2: T2, t3: T3): R;
}
interface CurriedFunction4<T1, T2, T3, T4, R> {
(): CurriedFunction4<T1, T2, T3, T4, R>;
(t1: T1): CurriedFunction3<T2, T3, T4, R>;
(t1: T1, t2: T2): CurriedFunction2<T3, T4, R>;
(t1: T1, t2: T2, t3: T3): CurriedFunction1<T4, R>;
(t1: T1, t2: T2, t3: T3, t4: T4): R;
}
interface CurriedFunction5<T1, T2, T3, T4, T5, R> {
(): CurriedFunction5<T1, T2, T3, T4, T5, R>;
(t1: T1): CurriedFunction4<T2, T3, T4, T5, R>;
(t1: T1, t2: T2): CurriedFunction3<T3, T4, T5, R>;
(t1: T1, t2: T2, t3: T3): CurriedFunction2<T4, T5, R>;
(t1: T1, t2: T2, t3: T3, t4: T4): CurriedFunction1<T5, R>;
(t1: T1, t2: T2, t3: T3, t4: T4, t5: T5): R;
}
declare function curry<T1, R>(func: (t1: T1) => R):
CurriedFunction1<T1, R>;
declare function curry<T1, T2, R>(func: (t1: T1, t2: T2) => R):
CurriedFunction2<T1, T2, R>;
declare function curry<T1, T2, T3, R>(func: (t1: T1, t2: T2, t3: T3) => R):
CurriedFunction3<T1, T2, T3, R>;
declare function curry<T1, T2, T3, T4, R>(func: (t1: T1, t2: T2, t3: T3, t4: T4) => R):
CurriedFunction4<T1, T2, T3, T4, R>;
declare function curry<T1, T2, T3, T4, T5, R>(func: (t1: T1, t2: T2, t3: T3, t4: T4, t5: T5) => R):
CurriedFunction5<T1, T2, T3, T4, T5, R>; |
Shouldn't a failing case be added to the test suite tho? It could be skipped from the build/test process as long as ts limitations remain in place, but it would live here for future work. Don't really see the value otherwise of only including tests that pass. |
Sure, PRs are welcome |
Tests that pass prevent regressions |
馃悶 Bug Report
Describe the bug
Currying a generic function loses the previous types.
Reproduce the bug
Expected behavior
f should infer
<B>(b: B) => ['a', B]
Or
<B>(b: B) => [string, B]
Additional context
The previous test would also fail for a binary rather than unary function, the return type would be lost anyway.
The text was updated successfully, but these errors were encountered: