diff --git a/jfp/jfp-tests.ts b/jfp/jfp-tests.ts
new file mode 100644
index 000000000..4612e3654
--- /dev/null
+++ b/jfp/jfp-tests.ts
@@ -0,0 +1,120 @@
+///
+
+function testFn () {};
+
+j(testFn);
+
+j.add(5, 6);
+j.always(true)();
+j.and(true, false) === false;
+j.apply(testFn, [1, 2, 3]);
+j.between([3, 7], 5) === true;
+j.call(testFn, 1, 2, 3);
+j.clone({});
+j.compact([]);
+j.compose(testFn, testFn)();
+j.composePredicate(j.isZero)(0);
+j.concat([], []);
+j.conj('foo', []);
+j.cons('foo', []);
+j.contains('foo', []);
+j.copyArray([]);
+j.countArguments(testFn);
+j.curry(testFn);
+j.deref('foo.bar.baz', {});
+j.difference([], []);
+j.divide(6, 3);
+j.drop(0, [1, 2, 3]);
+j.dropFirst([1, 2, 3]);
+j.dropLast([1, 2, 3]);
+j.dropUntil(j.isZero, []);
+j.fac(5);
+j.filter(j.isEven, [1, 2, 3, 4, 5]);
+j.find(j.isEven, []);
+j.first([1, 2, 3]);
+j.hasFirst([]);
+j.identity(5);
+j.inc(5);
+j.init([]);
+j.intersect([], []);
+j.isArray([]);
+j.isBoolean(true);
+j.isEmptyString('bar');
+j.isEven(3);
+j.isFunction(testFn);
+j.isInt(9.2);
+j.isMultipleOf(5, 35);
+j.isNegative(938);
+j.isNonNegative(3);
+j.isNonPositive(-99);
+j.isNonZero(0);
+j.isNull('not null');
+j.isNumber({});
+j.isNumeric('5.78');
+j.isObject({});
+j.isOdd(6);
+j.isPair([]);
+j.isPositive(9);
+j.isPrimitive({});
+j.isSingle([]);
+j.isString('Yup');
+j.isTriple([1, 2, 3]);
+j.isTruthy(1);
+j.isTuple([]);
+j.isType('number', 5);
+j.isUndefined(undefined);
+j.isZero(100);
+j.last([1, 2, 3]);
+j.lastIndex([]);
+j.leq(0, 6);
+j.less(9, 10);
+j.map(j.partial(j.add, 1), [1, 2, 3]);
+j.max(5, 6);
+j.maybe(null);
+j.maybeType('string', null);
+j.merge([], []);
+j.min(5, 6);
+j.mod(4, 3);
+j.modulo(4, 3);
+j.multiPartition(j.equal, [1, 2], [1, 2, 1, 2]);
+j.multiply(1, 2);
+j.not(true);
+j.nth(5, [1, 2, 3, 4, 5, 6, 7]);
+j.numberOf(j.isEven, [1, 2, 3, 4]);
+j.or(true, false);
+j.partial(testFn, 'foo')();
+j.partialReverse(testFn, 1, 2)();
+j.partition(j.isEven, [1, 2, 3, 4]);
+j.pick('foo', { foo: 'bar' });
+j.pipeline('foo', testFn, testFn);
+j.pluck('foo', { foo: 'bar' });
+j.pluckKeys(['foo'], { foo: 'bar' });
+j.range(5);
+j.range(5, 7);
+j.rcompose(testFn, testFn)();
+j.recur(testFn, 1, 2, 3);
+j.reduce(testFn, [1, 2, 3], []);
+j.repeat(10, testFn);
+j.rest([1, 2, 3, 4]);
+j.reverseArgs(testFn)();
+j.rpartial(testFn, 1, 2, 3);
+j.shortCircuit('foo', testFn, 'bar');
+j.slice(0, [1, 2, 3]);
+j.slice(0, [1, 2, 3], 1);
+j.some(j.isEven, [1, 2, 3]);
+j.sort([1, 2, 3, 4], function () { return 0});
+j.splitPartial(testFn, [], [])();
+j.subtract(6, 5);
+j.symmetricDifference([], []);
+j.take(5, [1, 2, 3, 4, 5, 6]);
+j.takeUntil(j.isEven, [1, 3, 5, 6, 7]);
+j.times(10, 'foo');
+j.toDec('10');
+j.toValues({ foo: 'bar' });
+j.transform([['foo', 'bar']], {});
+j.truncate(5.7);
+j.union([], []);
+j.unique([]);
+j.when(true, testFn);
+j.xor(true, true);
+j.zip([], []);
\ No newline at end of file
diff --git a/jfp/jfp.d.ts b/jfp/jfp.d.ts
new file mode 100644
index 000000000..2fd50a878
--- /dev/null
+++ b/jfp/jfp.d.ts
@@ -0,0 +1,847 @@
+// Type definitions for JFP
+// Project: http://cmstead.github.io/JFP
+// Definitions by: Chris Stead
+
+declare var j: j.JfpStatic
+
+declare module j {
+
+ interface JfpStatic {
+ /**
+ * jfp supports string function aliasing -- alias is a jfp function name and seeking behavior
+ * will happen against the jfp object only.
+ */
+ (alias: string, ...arguments: any[]): JfpCurriedOutput;
+ (externalFunction: (...arguments: any[]) => any, ...arguments: any[]): JfpCurriedOutput;
+ }
+
+ interface JfpCurriedOutput { }
+
+ //Array functions
+ interface JfpStatic {
+
+ /**
+ * Removes falsey values from an array
+ * @param values The array to compact
+ */
+ compact(values: any[]): any[];
+
+ /**
+ * Clones and concatenates two arrays
+ * @param values1 The array to concatenate to
+ * @param values2 The array to concatenate with
+ */
+ concat(values1: any[], values2: any[]): any[];
+
+ /**
+ * Appends value to clone of destination array
+ * @param value The value to add to the end of an array
+ * @param destination The array to be cloned and appended to
+ */
+ conj(value: any, destination: any[]): any[];
+
+ /**
+ * Prepends value to clone of destination array
+ * @param value The value to add to the beginning of an array
+ * @param destination The array to be cloned and prepended to
+ */
+ cons(value: any, destination: any[]): any[];
+
+ /**
+ * Returns a copy of passed array
+ */
+ copyArray(list: any[]): any[];
+
+ /**
+ * Takes the difference of sets A and B where the difference is A - B
+ */
+ difference(lista: any[], listb: any[]): any[];
+
+ /**
+ * Drops value at specified index from clone of array
+ * @param index Index to perform drop at
+ * @param values Array to remove value from
+ */
+ drop(index: number, values: any[]): any[];
+
+ /**
+ * Drops first element from clone of values array
+ * @param values Array to drop first value of
+ */
+ dropFirst(values: any[]): any[];
+
+ /**
+ * Drops last element from clone of values array
+ * @param values Array to drop last value from
+ */
+ dropLast(values: any[]): any[];
+
+ /**
+ * Drops values from array until predicate is satisfied
+ */
+ dropUntil(predicate: (...arguments: any[]) => boolean, list: any[]): any[];
+
+ /**
+ * Performs iterable function on each value of provided array
+ * @param iterable Function to perform on each value of array
+ * @param values Array to operate on
+ */
+ each(iteratable: (value: any) => void, values: any[]): any[];
+
+ /**
+ * Filters all values not passing provided predicate
+ * @param predicate Function which performs a boolean resultant operation on a value of the array
+ * @param values Array to filter
+ */
+ filter(predicate: (value: any) => boolean, values: any[]): any[];
+
+ /**
+ * Finds the first value in an array that satisfies provided predicate
+ * @param predicate Function which performs a boolean resultant operation on a value of the array
+ * @param values Array to run predicate against
+ */
+ find(predicate: (value: any) => boolean, values: any[]): any;
+
+ /**
+ * Drops last element of array
+ */
+ init(list: any[]): any[];
+
+ /**
+ * Takes the intersection of two arrays
+ */
+ intersect(lista: any[], listb: any[]): any[];
+
+ /**
+ * Returns the first value in an array
+ * @param values Array of values
+ */
+ first(values: any[]): any;
+
+ /**
+ * Returns last value in an array
+ * @param values Array of values
+ */
+ last(values: any[]): any;
+
+ /**
+ * Returns last index of an array
+ * @param values Array
+ */
+ lastIndex(values: any[]): number;
+
+ /**
+ * Maps functions into new array using mapper function
+ * @param mapper Mapping function
+ * @param values Array to map
+ */
+ map(mapper: (value: any) => any, values: any[]): any[];
+
+ /**
+ * Takes multiple partitions of a list using a partitioning predicate and criteria
+ */
+ multiPartition(predicate: (criterion: any, value: any) => boolean, criteria: any[], list: any[]): any[][];
+
+ /**
+ * Counts number of list values which satisfy predicate
+ */
+ numberOf(predicate: (value: any) => boolean, list: any[]): number;
+
+ /**
+ * Partitions array on values which pass and do not pass predicate
+ */
+ partition(predicate: (value: any) => boolean, list: any[]): any[][];
+
+ /**
+ * Returns nth value of passed array
+ * @param index Array index
+ * @param values Array of values
+ */
+ nth(index: number, values: any[]): any;
+
+ /**
+ * Reduces array using reducer function
+ * @param reducer Function to reduce values with
+ * @param values Array to reduce
+ */
+ reduce(reducer: (condition1: any, condition2: any) => any, values: any[]): any;
+
+ /**
+ * Reduces array using reducer function
+ * @param reducer Function to reduce values with
+ * @param values Array to reduce
+ * @param initialCondition Initial value to use in first reduction application
+ */
+ reduce(reducer: (condition1: any, condition2: any) => any, values: any[], initialCondition: any): any;
+
+ /**
+ * Returns all but the first element of array
+ * @param values Array to return the rest of
+ */
+ rest(values: any[]): any[];
+
+ /**
+ * Returns a slice of an array
+ * @param initialIndex index to start slicing at
+ * @param values Array to slice
+ */
+ slice(initialIndex: number, values: any[]): any[];
+
+ /**
+ * Returns a slice of an array
+ * @param initialIndex index to start slicing at
+ * @param values Array to slice
+ * @param lastIndex Index to end slice with
+ */
+ slice(initialIndex: number, values: any[], lastIndex: number): any[];
+
+ /**
+ * Returns true if at least one array element satisfies predicate, else false
+ */
+ some(predicate: (value: any) => boolean, list: any[]): boolean;
+
+ /**
+ * Sorts values in an array with an optional comparator arguments
+ */
+ sort(list: any[]): any[];
+ sort(list: any[], comparator: (a: any, b: any) => number): any[];
+
+ /**
+ * Takes the symmetric difference of two arrays
+ */
+ symmetricDifference(lista: any[], listb: any[]): any[];
+
+ /**
+ * Returns first n values of an array
+ * @param quantity Number of values to return
+ * @param values Array of values to take from
+ */
+ take(quantity: number, values: any[]): any[];
+
+ /**
+ * Takes values from array until predicate is satisfied
+ */
+ takeUntil(predicate: (value: any) => boolean, list: any[]): any[];
+
+ /**
+ * Takes the union of two arrays
+ */
+ union(lista: any[], listb: any[]): any[];
+
+ /**
+ * Returns array of values with duplicates removed
+ * @param values Array of values to filter by uniqueness
+ */
+ unique(values: any[]): any[];
+
+ /**
+ * Zips two arrays together into an array of arrays
+ */
+ zip(lista: any[], listb: any[]): any[][];
+
+ }
+
+ //Conditional functions
+ interface JfpStatic {
+
+ /**
+ * Returns preferred value if truthy, otherwise returns default value
+ * @param defaultValue Default value
+ * @param preferredValue Preferred value
+ */
+ either(defaultValue: any, preferredValue: any): any;
+
+ /**
+ * Returns provided value if truthy or matches datatype, otherwise returns default value
+ * @param defaultValue Default value
+ * @param preferredValue Preferred value
+ * @param datatype Type preferred value should be
+ */
+ either(defaultValue: any, preferredValue: any, datatype: string): any;
+
+ /**
+ * Returns preferred value if truthy, otherwise returns default value
+ * @param defaultValue Default value
+ * @param preferredValue Preferred value
+ * @param predicateValue Boolean switch to return default or preferred value
+ */
+ eitherIf(defaultValue: any, preferredValue: any, predicateValue: boolean): any;
+
+ /**
+ * Returns provided value if truthy, otherwise returns default value
+ * @param defaultValue Default value
+ * @param preferredValue Preferred value
+ * @param predicate Predicate function preferred value is tested against
+ */
+ eitherWhen(defaultValue: any, preferredValue: any, predicate: (value: any) => boolean): any;
+
+ /**
+ * Returns preferred value if truthy, otherwise null
+ * @param preferredValue Preferred value to check
+ */
+ maybe(preferredValue: any): any;
+
+ /**
+ * Returns preferred value if truthy or matches datatype, otherwise null
+ * @param preferredValue Preferred value to check
+ * @param datatype Datatype to match
+ */
+ maybe(preferredValue: any, datatype: string): any;
+
+ /**
+ * Executes function if value is truthy, otherwise returns default
+ * @param defaultValue
+ * @param userFn
+ * @param value
+ */
+ shortCircuit(defaultValue: any, userFn: (...arguments: any[]) => any, value: any): any;
+
+ /**
+ * Executes function when condition is true
+ * @param predicateValue Value to set behavior execution
+ * @param userFunction Behavior to execute
+ */
+ when(predicateValue: boolean, userFunction: (...arguments: any[]) => any): any;
+
+ /**
+ * Executes function when condition is true
+ * @param predicateValue Value to set behavior execution
+ * @param userFunction Behavior to execute
+ * @param ...arguments arguments for userFunction
+ */
+ when(predicateValue: boolean, userFunction: (...arguments: any[]) => any, ...arguments: any[]): any;
+
+ }
+
+ interface JfpStatic {
+
+ /**
+ * Converts value to decimal equivalent returns null if non-convertable
+ * @param value String or number value to convert
+ */
+ toDec(value: string): number;
+ toDec(value: number): number;
+
+ /**
+ * Converts an object literal into an array of values
+ * @param value Object literal
+ */
+ toValues(value: Object): any[];
+
+ }
+
+ interface JfpStatic {
+
+ /**
+ * Returns function which returns provided value
+ * Signature: (any) -> () -> any
+ * @param value Value to return from produced function
+ */
+ always(value: any): (...arguments: any[]) => any;
+
+ /**
+ * Applies an array of values to a function
+ * @param userFn Function to perform application against
+ * @param values Array of arguments for function
+ */
+ apply(userFn: (...arguments: any[]) => any, values: any[]): void;
+
+ /**
+ * Composes a set of functions into a new single function
+ * @param ...arguments Arguments for compose
+ */
+ compose(...arguments: ((...arguments: any[]) => any)[]): (...arguments: any[]) => any
+
+ /**
+ * Counts the number of arguments in a function declaration
+ * @param userFn Function to count arguments of
+ */
+ countArguments(userFn: (...arguments: any[]) => any): number;
+
+ /**
+ * Curries function until all arguments are satisfied
+ * @param userFn Function to curry
+ * @param ...argments Initial arguments for currying application
+ */
+ curry(userFn: (...arguments: any[]) => any): (...arguments: any[]) => any;
+ curry(userFn: (...arguments: any[]) => any): any;
+ curry(userFn: (...arguments: any[]) => any, ...arguments: any[]): (...arguments: any[]) => any;
+ curry(userFn: (...arguments: any[]) => any, ...arguments: any[]): any;
+
+ /**
+ * Executes passed function
+ * @param userFn
+ */
+ execute(userFn: (...arguments: any[]) => any): any;
+
+ /**
+ * Gets type of passed value
+ * @param value
+ */
+ getType(value: any): string;
+
+ /**
+ * Returns value passed to the function
+ * @param value Value to return
+ */
+ identity(value: any): any;
+
+ /**
+ * Applies values to a function and returns partially applied function
+ * @param userFn Function to apply values to
+ * @param ...arguments Values to apply
+ */
+ partial(userFn: (...arguments: any[]) => any): (...arguments: any[]) => any;
+ partial(userFn: (...arguments: any[]) => any, ...arguments: any[]): (...arguments: any[]) => any;
+
+ /**
+ * Pipelines or chains functions producing a single final output
+ * @param value Initial condition for function pipelining
+ * @param ...arguments Functions to chain/pipeline
+ */
+ pipeline(value: any, ...arguments: ((...arguments: any[]) => any)[]): any;
+
+ /**
+ * Recursion function to allow for tail-optimized recursion
+ * @param userFn Function to recur on
+ * @param ...arguments Initial condition arguments
+ */
+ recur(userFn: (...arguments: any[]) => any): any;
+ recur(userFn: (...arguments: any[]) => any, ...arguments: any[]): any;
+
+ /**
+ * Reverses arguments of provided function
+ * @param userFn
+ */
+ reverseArgs(userFn: (...arguments: any[]) => any): (...arguments: any[]) => any;
+
+ /**
+ * Performs a right partial application on a function
+ * @param userFn Function to apply arguments
+ * @param ...arguments Inital arguments
+ */
+ rpartial(userFn: (...arguments: any[]) => any): any;
+ rpartial(userFn: (...arguments: any[]) => any, ...arguments: any[]): any;
+
+ /**
+ * Performs a split partial application
+ * @param userFn
+ * @param leftArgs
+ * @param rightArgs
+ */
+ splitPartial(userFn: (...arguments: any[]) => any, leftArgs: any[], rightArgs: any[]): (...arguments: any[]) => any;
+ }
+
+ // Predicate functions
+ interface JfpStatic {
+
+ /**
+ * Returns true if array contains provided value, else false
+ */
+ contains(value: any, list: any[]): boolean;
+
+ /**
+ * Checks value equality of two arguments
+ * @param valuea
+ * @param valueb
+ */
+ equal(valuea: any, valueb: any): boolean;
+
+ /**
+ * Checks if every value in an array passes a predicate
+ */
+ every(predicate: (value: any) => boolean, list: any[]): boolean;
+
+ /**
+ * Checks if value is an empty string
+ * @param value
+ */
+ isEmptyString(value: any): boolean;
+
+ /**
+ * Checks if value is null
+ * @param value
+ */
+ isNull(value: any): boolean;
+
+ /**
+ * Checks if value is of type passed as string
+ * @param type
+ * @param value
+ */
+ isType(type: string, value: any): boolean;
+
+ /**
+ * Checks if passed value is an array
+ */
+ isArray(value: any): boolean;
+
+ /**
+ * Checks if passed value is a boolean
+ */
+ isBoolean(value: any): boolean;
+
+ /**
+ * Checks if passed value is a function
+ */
+ isFunction(value: any): boolean;
+
+ /**
+ * Checks if passed value is a number
+ */
+ isNumber(value: any): boolean;
+
+ /**
+ * Checks if passed value is an object
+ */
+ isObject(value: any): boolean;
+
+ /**
+ * Checks if passed value is a string
+ */
+ isString(value: any): boolean;
+
+ /**
+ * Checks if passed value is undefined
+ */
+ isUndefined(value: any): boolean;
+
+ /**
+ * Checks if passed value is a tuple
+ */
+ isTuple(value: any): boolean;
+
+ /**
+ * Checks if passed value is a tuple of length 2
+ */
+ isPair(value: any): boolean;
+
+ /**
+ * Checks if passed value is a tuple of length 1
+ */
+ isSingle(value: any): boolean;
+
+ /**
+ * Checks if passed value is a tuple of length 3
+ */
+ isTriple(value: any): boolean;
+
+ /**
+ * Checks that passed value is an array which contains a first value
+ */
+ hasFirst(value: any): boolean;
+
+ /**
+ * Checks if passed value is either a number or a numeric string
+ */
+ isNumeric(value: any): boolean;
+
+ /**
+ * Checks if passed value is a primitive Javascript type
+ */
+ isPrimitive(value: any): boolean;
+
+ /**
+ * Checks if passed value is truthy
+ */
+ isTruthy(value: any): boolean;
+
+ /**
+ * Returns boolean inverse of passed value
+ */
+ not(value: boolean): boolean;
+
+ }
+
+ // Composite functions
+ interface JfpStatic {
+
+ /**
+ * Clones values to an optional depth
+ */
+ clone(value: any): any;
+ clone(value: any, depth: number): any;
+
+ /**
+ * Composes functions together in common nested order
+ */
+ compose(...arguments: ((...arguments: any[]) => any)[]): (...arguments: any[]) => any;
+
+ /**
+ * Curries passed function and applies optional arguments
+ */
+ curry(fn: (...arguments: any[]) => any, ...arguments: any[]): (...arguments: any[]) => any;
+
+ /**
+ * Returns either typed value based on type parameter
+ */
+ eitherType(type: string, defaultValue: any, value: any): any;
+
+ /**
+ * Returns maybe typed value based on type parameter
+ */
+ maybeType(type: string, value: any): any;
+
+ /**
+ * Returns a partially applied function with remaining arguments reversed
+ */
+ partialReverse(fn: (...arguments: any[]) => any, ...arguments: any[]): (...arguments: any[]) => any;
+
+ /**
+ * Passes chains functions together with an initial arguments
+ */
+ pipeline(value: any, ...arguments: ((...arguments: any[]) => any)[]): any;
+
+ /**
+ * Composes functions executing from left to right
+ */
+ rcompose(...arguments: ((...arguments: any[]) => any)[]): (...arguments: any[]) => any;
+
+ /**
+ * Executes a trampolined tail-optimized recursive function
+ */
+ recur(fn: (...arguments: any[]) => any): any;
+
+ /**
+ * Repeats action n times
+ */
+ repeat(count: number, action: (...arguments: any[]) => any): any;
+
+ /**
+ * Outputs a string composed of n copies of base string
+ */
+ times(count: number, value: string): string;
+
+ }
+
+ interface JfpStatic {
+
+ /**
+ * Converts string to decimal safely
+ */
+ toDec(value: any): number;
+
+ }
+
+ interface JfpStatic {
+
+ /**
+ * Adds two numbers
+ */
+ add(a: number, b: number): number;
+
+ /**
+ * Divides first number by second
+ */
+ divide(numerator: number, denominator: number): number;
+
+ /**
+ * Takes the factorial of passed number
+ */
+ fac(n: number): number;
+
+ /**
+ * Increments a number
+ */
+ inc(value: number): number;
+
+ /**
+ * Takes the maximum of two numbers
+ */
+ max(a: number, b: number): number;
+
+ /**
+ * Takes the minimum of two numbers
+ */
+ min(a: number, b: number): number;
+
+ /**
+ * Takes the modulus of first number against second number
+ */
+ mod(a: number, b: number): number;
+
+ /**
+ * Takes mathematical modulo of first number against second number
+ */
+ modulo(a: number, b: number): number;
+
+ /**
+ * Multiplies two numbers
+ */
+ multiply(a: number, b: number): number;
+
+ /**
+ * Creates a range either from 0 to an integer or from one integer to another
+ */
+ range(end: number): number[];
+ range(start: number, end: number): number[];
+
+ /**
+ * Subtracts second argument from first
+ */
+ subtract(a: number, b: number): number;
+
+ /**
+ * Truncates number to floor if positive or to ceil if negative
+ */
+ truncate(value: number): number;
+
+ }
+
+ interface JfpStatic {
+
+ /**
+ * Checks if number is negative
+ */
+ isNegative(value: number): boolean;
+
+ /**
+ * Checks if number is positive
+ */
+ isPositive(value: number): boolean;
+
+ /**
+ * Checks if number is 0
+ */
+ isZero(value: number): boolean;
+
+ /**
+ * Checks if number is between two values
+ */
+ between(bounds: number[], value: number): boolean;
+
+ /**
+ * Checks if value is even
+ */
+ isEven(value: number): boolean;
+
+ /**
+ * Checks if value is an integer
+ */
+ isInt(value: number): boolean;
+
+ /**
+ * Checks if value is a multiple of base value
+ */
+ isMultipleOf(base: number, value: number): boolean;
+
+ /**
+ * Checks if value is positive or 0
+ */
+ isNonNegative(value: number): boolean;
+
+ /**
+ * Checks if value is negative or 0
+ */
+ isNonPositive(value: number): boolean;
+
+ /**
+ * Checks if value is not 0
+ */
+ isNonZero(value: number): boolean;
+
+ /**
+ * Checks if value is odd
+ */
+ isOdd(value: number): boolean;
+
+ /**
+ * Checks if a is greater or equal to b
+ */
+ geq(a: number, b: number): boolean;
+
+ /**
+ * Checks if a is greater than b
+ */
+ greater(a: number, b: number): boolean;
+
+ /**
+ * Checks if a is less than or equal to b
+ */
+ leq(a: number, b: number): boolean;
+
+ /**
+ * Checks if a is less than b
+ */
+ less(a: number, b: number): boolean;
+
+ }
+
+ interface JfpStatic {
+
+ /**
+ * Gets object keys
+ */
+ getKeys(dataset: {}): string[];
+
+ /**
+ * Merges right object into a copy of left object
+ */
+ merge(left: {}, right: {}): {};
+
+ /**
+ * Picks key from object
+ */
+ pick(key: string, dataset: {}): any;
+
+ }
+
+ interface JfpStatic {
+
+ /**
+ * Traverses object tree and retrieves dot-delimited key or returns null
+ */
+ deref(key: string, dataset: {}): any;
+
+ /**
+ * Picks value from object by key and returns a new object containing key value pair
+ */
+ pluck(key: string, dataset: {}): {};
+
+ /**
+ * Performs pluck across an array of keys, returns a single object containing all key value pairs
+ */
+ pluckKeys(keys: string[], dataset: {}): {};
+
+ /**
+ * Converts object to an array of values
+ */
+ toValues(dataset: {}): any[];
+
+ /**
+ * Transforms object to a new object containing transformed keys
+ */
+ transform(transformation: string[][], dataset: {}): {};
+
+ }
+
+ interface JfpStatic {
+
+ /**
+ * Performs a conjunction (and) operation on two or more booleans
+ */
+ and(a: boolean, b: boolean, ...arguments: boolean[]): boolean;
+
+ /**
+ * Performs a disjunction (or) operation on two or more booleans
+ */
+ or(a: boolean, b: boolean, ...arguments: boolean[]): boolean;
+
+ /**
+ * Performs an exclusive or operation on two booleans
+ */
+ xor(a: boolean, b: boolean): boolean;
+
+ /**
+ * Creates composite predicate which performs each check on a value and then conjoins the result
+ */
+ composePredicate(...arguments: ((...arguments: any[]) => boolean)[]): (...arguments: any[]) => boolean;
+
+
+ }
+
+}
+
+declare module "jfp" {
+ export = j;
+}
\ No newline at end of file