Skip to content

Commit

Permalink
Improve typings for compose function (#1868)
Browse files Browse the repository at this point in the history
  • Loading branch information
aikoven authored and timdorr committed Jul 26, 2016
1 parent 13add05 commit 085eaec
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 21 deletions.
68 changes: 50 additions & 18 deletions index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -357,6 +357,11 @@ export function bindActionCreators<

/* compose */

type Func0<R> = () => R;
type Func1<T1, R> = (a1: T1) => R;
type Func2<T1, T2, R> = (a1: T1, a2: T2) => R;
type Func3<T1, T2, T3, R> = (a1: T1, a2: T2, a3: T3, ...args: any[]) => R;

/**
* Composes single-argument functions from right to left. The rightmost
* function can take multiple arguments as it provides the signature for the
Expand All @@ -367,27 +372,54 @@ export function bindActionCreators<
* to left. For example, `compose(f, g, h)` is identical to doing
* `(...args) => f(g(h(...args)))`.
*/
export function compose(): <R>(a: R, ...args: any[]) => R;
export function compose(): <R>(a: R) => R;

export function compose<A, R>(
f1: (b: A) => R,
f2: (...args: any[]) => A
): (...args: any[]) => R;
export function compose<F extends Function>(f: F): F;

/* two functions */
export function compose<A, R>(
f1: (b: A) => R, f2: Func0<A>
): Func0<R>;
export function compose<A, T1, R>(
f1: (b: A) => R, f2: Func1<T1, A>
): Func1<T1, R>;
export function compose<A, T1, T2, R>(
f1: (b: A) => R, f2: Func2<T1, T2, A>
): Func2<T1, T2, R>;
export function compose<A, T1, T2, T3, R>(
f1: (b: A) => R, f2: Func3<T1, T2, T3, A>
): Func3<T1, T2, T3, R>;

/* three functions */
export function compose<A, B, R>(
f1: (b: B) => R,
f2: (a: A) => B,
f3: (...args: any[]) => A
): (...args: any[]) => R;

f1: (b: B) => R, f2: (a: A) => B, f3: Func0<A>
): Func0<R>;
export function compose<A, B, T1, R>(
f1: (b: B) => R, f2: (a: A) => B, f3: Func1<T1, A>
): Func1<T1, R>;
export function compose<A, B, T1, T2, R>(
f1: (b: B) => R, f2: (a: A) => B, f3: Func2<T1, T2, A>
): Func2<T1, T2, R>;
export function compose<A, B, T1, T2, T3, R>(
f1: (b: B) => R, f2: (a: A) => B, f3: Func3<T1, T2, T3, A>
): Func3<T1, T2, T3, R>;

/* four functions */
export function compose<A, B, C, R>(
f1: (b: C) => R,
f2: (a: B) => C,
f3: (a: A) => B,
f4: (...args: any[]) => A
): (...args: any[]) => R;

export function compose<R>(
f1: (a: any) => R,
f1: (b: C) => R, f2: (a: B) => C, f3: (a: A) => B, f4: Func0<A>
): Func0<R>;
export function compose<A, B, C, T1, R>(
f1: (b: C) => R, f2: (a: B) => C, f3: (a: A) => B, f4: Func1<T1, A>
): Func1<T1, R>;
export function compose<A, B, C, T1, T2, R>(
f1: (b: C) => R, f2: (a: B) => C, f3: (a: A) => B, f4: Func2<T1, T2, A>
): Func2<T1, T2, R>;
export function compose<A, B, C, T1, T2, T3, R>(
f1: (b: C) => R, f2: (a: B) => C, f3: (a: A) => B, f4: Func3<T1, T2, T3, A>
): Func3<T1, T2, T3, R>;

/* rest */
export function compose<A, B, C, R>(
f1: (b: C) => R, f2: (a: B) => C, f3: (a: A) => B,
...funcs: Function[]
): (...args: any[]) => R;
19 changes: 16 additions & 3 deletions test/typescript/compose.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,20 @@ const t4: (a: string) => number = compose(


const t5: number = compose(stringToNumber, numberToString, numberToNumber)(5);
const t6: string = compose(numberToString, stringToNumber, numberToString, numberToNumber)(5);
const t6: string = compose(numberToString, stringToNumber, numberToString,
numberToNumber)(5);

const t7: string = compose<string>(
numberToString, numberToNumber, stringToNumber, numberToString, stringToNumber)("fo");
const t7: string = compose(
numberToString, numberToNumber, stringToNumber, numberToString,
stringToNumber)("fo");


const multiArgFn = (a: string, b: number, c: boolean): string => 'foo'

const t8: string = compose(multiArgFn)('bar', 42, true);
const t9: number = compose(stringToNumber, multiArgFn)('bar', 42, true);
const t10: string = compose(numberToString, stringToNumber,
multiArgFn)('bar', 42, true);

const t11: number = compose(stringToNumber, numberToString, stringToNumber,
multiArgFn)('bar', 42, true);

0 comments on commit 085eaec

Please sign in to comment.