@uirouter/core
Version:
UI-Router Core: Framework agnostic, State-based routing for JavaScript Single Page Apps
161 lines (160 loc) • 6.84 kB
TypeScript
/**
* Higher order functions
*
* These utility functions are exported, but are subject to change without notice.
*
* @packageDocumentation
*/
import { Predicate } from './common';
/**
* Returns a new function for [Partial Application](https://en.wikipedia.org/wiki/Partial_application) of the original function.
*
* Given a function with N parameters, returns a new function that supports partial application.
* The new function accepts anywhere from 1 to N parameters. When that function is called with M parameters,
* where M is less than N, it returns a new function that accepts the remaining parameters. It continues to
* accept more parameters until all N parameters have been supplied.
*
*
* This contrived example uses a partially applied function as an predicate, which returns true
* if an object is found in both arrays.
* @example
* ```
* // returns true if an object is in both of the two arrays
* function inBoth(array1, array2, object) {
* return array1.indexOf(object) !== -1 &&
* array2.indexOf(object) !== 1;
* }
* let obj1, obj2, obj3, obj4, obj5, obj6, obj7
* let foos = [obj1, obj3]
* let bars = [obj3, obj4, obj5]
*
* // A curried "copy" of inBoth
* let curriedInBoth = curry(inBoth);
* // Partially apply both the array1 and array2
* let inFoosAndBars = curriedInBoth(foos, bars);
*
* // Supply the final argument; since all arguments are
* // supplied, the original inBoth function is then called.
* let obj1InBoth = inFoosAndBars(obj1); // false
*
* // Use the inFoosAndBars as a predicate.
* // Filter, on each iteration, supplies the final argument
* let allObjs = [ obj1, obj2, obj3, obj4, obj5, obj6, obj7 ];
* let foundInBoth = allObjs.filter(inFoosAndBars); // [ obj3 ]
*
* ```
*
* @param fn
* @returns {*|function(): (*|any)}
*/
export declare function curry(fn: Function): Function;
/**
* Given a varargs list of functions, returns a function that composes the argument functions, right-to-left
* given: f(x), g(x), h(x)
* let composed = compose(f,g,h)
* then, composed is: f(g(h(x)))
*/
export declare function compose(): () => any;
/**
* Given a varargs list of functions, returns a function that is composes the argument functions, left-to-right
* given: f(x), g(x), h(x)
* let piped = pipe(f,g,h);
* then, piped is: h(g(f(x)))
*/
export declare function pipe(...funcs: Function[]): (obj: any) => any;
/**
* Given a property name, returns a function that returns that property from an object
* let obj = { foo: 1, name: "blarg" };
* let getName = prop("name");
* getName(obj) === "blarg"
*/
export declare const prop: (name: string) => (obj: any) => any;
/**
* Given a property name and a value, returns a function that returns a boolean based on whether
* the passed object has a property that matches the value
* let obj = { foo: 1, name: "blarg" };
* let getName = propEq("name", "blarg");
* getName(obj) === true
*/
export declare const propEq: Function;
/**
* Given a dotted property name, returns a function that returns a nested property from an object, or undefined
* let obj = { id: 1, nestedObj: { foo: 1, name: "blarg" }, };
* let getName = prop("nestedObj.name");
* getName(obj) === "blarg"
* let propNotFound = prop("this.property.doesnt.exist");
* propNotFound(obj) === undefined
*/
export declare const parse: (name: string) => any;
/**
* Given a function that returns a truthy or falsey value, returns a
* function that returns the opposite (falsey or truthy) value given the same inputs
*/
export declare const not: (fn: Predicate<any>) => Predicate<any>;
/**
* Given two functions that return truthy or falsey values, returns a function that returns truthy
* if both functions return truthy for the given arguments
*/
export declare function and(fn1: Predicate<any>, fn2: Predicate<any>): Predicate<any>;
/**
* Given two functions that return truthy or falsey values, returns a function that returns truthy
* if at least one of the functions returns truthy for the given arguments
*/
export declare function or(fn1: Predicate<any>, fn2: Predicate<any>): Predicate<any>;
/**
* Check if all the elements of an array match a predicate function
*
* @param fn1 a predicate function `fn1`
* @returns a function which takes an array and returns true if `fn1` is true for all elements of the array
*/
export declare const all: (fn1: Predicate<any>) => (arr: any[]) => boolean;
export declare const any: (fn1: Predicate<any>) => (arr: any[]) => boolean;
/** Given a class, returns a Predicate function that returns true if the object is of that class */
export declare const is: <T>(ctor: new (...args: any[]) => T) => (obj: any) => obj is T;
/** Given a value, returns a Predicate function that returns true if another value is === equal to the original value */
export declare const eq: (comp: any) => Predicate<any>;
/** Given a value, returns a function which returns the value */
export declare const val: <T>(v: T) => () => T;
export declare function invoke(fnName: string): Function;
export declare function invoke(fnName: string, args: any[]): Function;
/**
* Sorta like Pattern Matching (a functional programming conditional construct)
*
* See http://c2.com/cgi/wiki?PatternMatching
*
* This is a conditional construct which allows a series of predicates and output functions
* to be checked and then applied. Each predicate receives the input. If the predicate
* returns truthy, then its matching output function (mapping function) is provided with
* the input and, then the result is returned.
*
* Each combination (2-tuple) of predicate + output function should be placed in an array
* of size 2: [ predicate, mapFn ]
*
* These 2-tuples should be put in an outer array.
*
* @example
* ```
*
* // Here's a 2-tuple where the first element is the isString predicate
* // and the second element is a function that returns a description of the input
* let firstTuple = [ angular.isString, (input) => `Heres your string ${input}` ];
*
* // Second tuple: predicate "isNumber", mapfn returns a description
* let secondTuple = [ angular.isNumber, (input) => `(${input}) That's a number!` ];
*
* let third = [ (input) => input === null, (input) => `Oh, null...` ];
*
* let fourth = [ (input) => input === undefined, (input) => `notdefined` ];
*
* let descriptionOf = pattern([ firstTuple, secondTuple, third, fourth ]);
*
* console.log(descriptionOf(undefined)); // 'notdefined'
* console.log(descriptionOf(55)); // '(55) That's a number!'
* console.log(descriptionOf("foo")); // 'Here's your string foo'
* ```
*
* @param struct A 2D array. Each element of the array should be an array, a 2-tuple,
* with a Predicate and a mapping/output function
* @returns {function(any): *}
*/
export declare function pattern(struct: Function[][]): Function;