-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.ts
40 lines (31 loc) · 965 Bytes
/
index.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
import { useCallback, DependencyList } from 'react'
type Curried<A extends any[], R> = <P extends Partial<A>>(
...args: P
) => P extends A
? R
: A extends [...SameLength<P>, ...infer S]
? S extends any[]
? Curried<S, R>
: never
: never
type SameLength<T extends any[]> = Extract<{ [K in keyof T]: any }, any[]>
const curry = <T extends any[], R>(fn: (...args: T) => R) => {
return ((...fnArgs: T) => {
let prevArgs: any[] = []
const nextFn = (...args: T) => {
prevArgs = prevArgs.concat(args)
if (!fn.length) {
return fn(...(prevArgs as T))
}
if (prevArgs.length >= fn.length) {
return () => fn(...(prevArgs as T))
}
return nextFn
}
return nextFn(...fnArgs)
}) as Curried<T, typeof fn extends (...args: undefined[]) => R ? R : () => R>
}
export const useCurry = <T extends any[], R>(
fn: (...args: T) => R,
deps: DependencyList
) => useCallback(curry(fn), deps)