//_.groupBy
interface LoDashStatic {
        /**
         * Creates an object composed of keys generated from the results of running each element of collection through
         * iteratee. The corresponding value of each key is an array of the elements responsible for generating the
         * key. The iteratee is bound to thisArg and invoked with three arguments:
         * (value, index|key, collection).
         *
         * If a property name is provided for iteratee the created _.property style callback returns the property
         * value of the given element.
         *
         * If a value is also provided for thisArg the created _.matchesProperty style callback returns true for
         * elements that have a matching property value, else false.
         *
         * If an object is provided for iteratee the created _.matches style callback returns true for elements that
         * have the properties of the given object, else false.
         *
         * @param collection The collection to iterate over.
         * @param iteratee The function invoked per iteration.
         * @param thisArg The this binding of iteratee.
         * @return Returns the composed aggregate object.
         */
        groupBy<T, TKey>(
            collection: List<T>,
            iteratee?: ListIterator<T, TKey>,
            thisArg?: any
        ): Dictionary<T[]>;

        /**
         * @see _.groupBy
         */
        groupBy<T>(
            collection: List<any>,
            iteratee?: ListIterator<T, any>,
            thisArg?: any
        ): Dictionary<T[]>;

        /**
         * @see _.groupBy
         */
        groupBy<T, TKey>(
            collection: Dictionary<T>,
            iteratee?: DictionaryIterator<T, TKey>,
            thisArg?: any
        ): Dictionary<T[]>;

        /**
         * @see _.groupBy
         */
        groupBy<T>(
            collection: Dictionary<any>,
            iteratee?: DictionaryIterator<T, any>,
            thisArg?: any
        ): Dictionary<T[]>;

        /**
         * @see _.groupBy
         */
        groupBy<T, TValue>(
            collection: List<T>|Dictionary<T>,
            iteratee?: string,
            thisArg?: TValue
        ): Dictionary<T[]>;

        /**
         * @see _.groupBy
         */
        groupBy<T>(
            collection: List<T>|Dictionary<T>,
            iteratee?: string,
            thisArg?: any
        ): Dictionary<T[]>;

        /**
         * @see _.groupBy
         */
        groupBy<TWhere, T>(
            collection: List<T>|Dictionary<T>,
            iteratee?: TWhere
        ): Dictionary<T[]>;

        /**
         * @see _.groupBy
         */
        groupBy<T>(
            collection: List<T>|Dictionary<T>,
            iteratee?: Object
        ): Dictionary<T[]>;
    }


interface LoDashImplicitWrapper<T> {
        /**
         * @see _.groupBy
         */
        groupBy<TKey>(
            iteratee?: ListIterator<T, TKey>,
            thisArg?: any
        ): LoDashImplicitObjectWrapper<Dictionary<T[]>>;
    }


interface LoDashImplicitArrayWrapper<T> {
        /**
         * @see _.groupBy
         */
        groupBy<TKey>(
            iteratee?: ListIterator<T, TKey>,
            thisArg?: any
        ): LoDashImplicitObjectWrapper<Dictionary<T[]>>;

        /**
         * @see _.groupBy
         */
        groupBy<TValue>(
            iteratee?: string,
            thisArg?: TValue
        ): LoDashImplicitObjectWrapper<Dictionary<T[]>>;

        /**
         * @see _.groupBy
         */
        groupBy<TWhere>(
            iteratee?: TWhere
        ): LoDashImplicitObjectWrapper<Dictionary<T[]>>;
    }


interface LoDashImplicitObjectWrapper<T> {
        /**
         * @see _.groupBy
         */
        groupBy<T, TKey>(
            iteratee?: ListIterator<T, TKey>|DictionaryIterator<T, TKey>,
            thisArg?: any
        ): LoDashImplicitObjectWrapper<Dictionary<T[]>>;

        /**
         * @see _.groupBy
         */
        groupBy<T>(
            iteratee?: ListIterator<T, any>|DictionaryIterator<T, any>,
            thisArg?: any
        ): LoDashImplicitObjectWrapper<Dictionary<T[]>>;

        /**
         * @see _.groupBy
         */
        groupBy<T, TValue>(
            iteratee?: string,
            thisArg?: TValue
        ): LoDashImplicitObjectWrapper<Dictionary<T[]>>;

        /**
         * @see _.groupBy
         */
        groupBy<T>(
            iteratee?: string,
            thisArg?: any
        ): LoDashImplicitObjectWrapper<Dictionary<T[]>>;

        /**
         * @see _.groupBy
         */
        groupBy<TWhere, T>(
            iteratee?: TWhere
        ): LoDashImplicitObjectWrapper<Dictionary<T[]>>;

        /**
         * @see _.groupBy
         */
        groupBy<T>(
            iteratee?: Object
        ): LoDashImplicitObjectWrapper<Dictionary<T[]>>;
    }


interface LoDashExplicitWrapper<T> {
        /**
         * @see _.groupBy
         */
        groupBy<TKey>(
            iteratee?: ListIterator<T, TKey>,
            thisArg?: any
        ): LoDashExplicitObjectWrapper<Dictionary<T[]>>;
    }


interface LoDashExplicitArrayWrapper<T> {
        /**
         * @see _.groupBy
         */
        groupBy<TKey>(
            iteratee?: ListIterator<T, TKey>,
            thisArg?: any
        ): LoDashExplicitObjectWrapper<Dictionary<T[]>>;

        /**
         * @see _.groupBy
         */
        groupBy<TValue>(
            iteratee?: string,
            thisArg?: TValue
        ): LoDashExplicitObjectWrapper<Dictionary<T[]>>;

        /**
         * @see _.groupBy
         */
        groupBy<TWhere>(
            iteratee?: TWhere
        ): LoDashExplicitObjectWrapper<Dictionary<T[]>>;
    }


interface LoDashExplicitObjectWrapper<T> {
        /**
         * @see _.groupBy
         */
        groupBy<T, TKey>(
            iteratee?: ListIterator<T, TKey>|DictionaryIterator<T, TKey>,
            thisArg?: any
        ): LoDashExplicitObjectWrapper<Dictionary<T[]>>;

        /**
         * @see _.groupBy
         */
        groupBy<T>(
            iteratee?: ListIterator<T, any>|DictionaryIterator<T, any>,
            thisArg?: any
        ): LoDashExplicitObjectWrapper<Dictionary<T[]>>;

        /**
         * @see _.groupBy
         */
        groupBy<T, TValue>(
            iteratee?: string,
            thisArg?: TValue
        ): LoDashExplicitObjectWrapper<Dictionary<T[]>>;

        /**
         * @see _.groupBy
         */
        groupBy<T>(
            iteratee?: string,
            thisArg?: any
        ): LoDashExplicitObjectWrapper<Dictionary<T[]>>;

        /**
         * @see _.groupBy
         */
        groupBy<TWhere, T>(
            iteratee?: TWhere
        ): LoDashExplicitObjectWrapper<Dictionary<T[]>>;

        /**
         * @see _.groupBy
         */
        groupBy<T>(
            iteratee?: Object
        ): LoDashExplicitObjectWrapper<Dictionary<T[]>>;
    }


//_.includes
interface LoDashStatic {
        /**
         * Checks if target is in collection using SameValueZero for equality comparisons. If fromIndex is negative,
         * it’s used as the offset from the end of collection.
         *
         * @param collection The collection to search.
         * @param target The value to search for.
         * @param fromIndex The index to search from.
         * @return True if the target element is found, else false.
         */
        includes<T>(
            collection: List<T>|Dictionary<T>,
            target: T,
            fromIndex?: number
        ): boolean;

        /**
         * @see _.includes
         */
        includes(
            collection: string,
            target: string,
            fromIndex?: number
        ): boolean;
    }


interface LoDashImplicitArrayWrapper<T> {
        /**
         * @see _.includes
         */
        includes(
            target: T,
            fromIndex?: number
        ): boolean;
    }


interface LoDashImplicitObjectWrapper<T> {
        /**
         * @see _.includes
         */
        includes<TValue>(
            target: TValue,
            fromIndex?: number
        ): boolean;
    }


interface LoDashImplicitWrapper<T> {
        /**
         * @see _.includes
         */
        includes(
            target: string,
            fromIndex?: number
        ): boolean;
    }


interface LoDashExplicitArrayWrapper<T> {
        /**
         * @see _.includes
         */
        includes(
            target: T,
            fromIndex?: number
        ): LoDashExplicitWrapper<boolean>;
    }


interface LoDashExplicitObjectWrapper<T> {
        /**
         * @see _.includes
         */
        includes<TValue>(
            target: TValue,
            fromIndex?: number
        ): LoDashExplicitWrapper<boolean>;
    }


interface LoDashExplicitWrapper<T> {
        /**
         * @see _.includes
         */
        includes(
            target: string,
            fromIndex?: number
        ): LoDashExplicitWrapper<boolean>;
    }


//_.keyBy
interface LoDashStatic {
        /**
         * Creates an object composed of keys generated from the results of running each element of collection through
         * iteratee. The corresponding value of each key is the last element responsible for generating the key. The
         * iteratee function is bound to thisArg and invoked with three arguments:
         * (value, index|key, collection).
         *
         * If a property name is provided for iteratee the created _.property style callback returns the property
         * value of the given element.
         *
         * If a value is also provided for thisArg the created _.matchesProperty style callback returns true for
         * elements that have a matching property value, else false.
         *
         * If an object is provided for iteratee the created _.matches style callback returns true for elements that
         * have the properties of the given object, else false.
         *
         * @param collection The collection to iterate over.
         * @param iteratee The function invoked per iteration.
         * @param thisArg The this binding of iteratee.
         * @return Returns the composed aggregate object.
         */
        keyBy<T>(
            collection: List<T>,
            iteratee?: ListIterator<T, any>,
            thisArg?: any
        ): Dictionary<T>;

        /**
         * @see _.keyBy
         */
        keyBy<T>(
            collection: NumericDictionary<T>,
            iteratee?: NumericDictionaryIterator<T, any>,
            thisArg?: any
        ): Dictionary<T>;

        /**
         * @see _.keyBy
         */
        keyBy<T>(
            collection: Dictionary<T>,
            iteratee?: DictionaryIterator<T, any>,
            thisArg?: any
        ): Dictionary<T>;

        /**
         * @see _.keyBy
         */
        keyBy<T>(
            collection: List<T>|NumericDictionary<T>|Dictionary<T>,
            iteratee?: string,
            thisArg?: any
        ): Dictionary<T>;

        /**
         * @see _.keyBy
         */
        keyBy<W extends Object, T>(
            collection: List<T>|NumericDictionary<T>|Dictionary<T>,
            iteratee?: W
        ): Dictionary<T>;

        /**
         * @see _.keyBy
         */
        keyBy<T>(
            collection: List<T>|NumericDictionary<T>|Dictionary<T>,
            iteratee?: Object
        ): Dictionary<T>;
    }


interface LoDashImplicitWrapper<T> {
        /**
         * @see _.keyBy
         */
        keyBy(
            iteratee?: ListIterator<T, any>,
            thisArg?: any
        ): LoDashImplicitObjectWrapper<Dictionary<T>>;
    }


interface LoDashImplicitArrayWrapper<T> {
        /**
         * @see _.keyBy
         */
        keyBy(
            iteratee?: ListIterator<T, any>,
            thisArg?: any
        ): LoDashImplicitObjectWrapper<Dictionary<T>>;

        /**
         * @see _.keyBy
         */
        keyBy(
            iteratee?: string,
            thisArg?: any
        ): LoDashImplicitObjectWrapper<Dictionary<T>>;

        /**
         * @see _.keyBy
         */
        keyBy<W extends Object>(
            iteratee?: W
        ): LoDashImplicitObjectWrapper<Dictionary<T>>;
    }


interface LoDashImplicitObjectWrapper<T> {
        /**
         * @see _.keyBy
         */
        keyBy<T>(
            iteratee?: ListIterator<T, any>|NumericDictionaryIterator<T, any>|DictionaryIterator<T, any>,
            thisArg?: any
        ): LoDashImplicitObjectWrapper<Dictionary<T>>;

        /**
         * @see _.keyBy
         */
        keyBy<T>(
            iteratee?: string,
            thisArg?: any
        ): LoDashImplicitObjectWrapper<Dictionary<T>>;

        /**
         * @see _.keyBy
         */
        keyBy<W extends Object, T>(
            iteratee?: W
        ): LoDashImplicitObjectWrapper<Dictionary<T>>;

        /**
         * @see _.keyBy
         */
        keyBy<T>(
            iteratee?: Object
        ): LoDashImplicitObjectWrapper<Dictionary<T>>;
    }


interface LoDashExplicitWrapper<T> {
        /**
         * @see _.keyBy
         */
        keyBy(
            iteratee?: ListIterator<T, any>,
            thisArg?: any
        ): LoDashExplicitObjectWrapper<Dictionary<T>>;
    }


interface LoDashExplicitArrayWrapper<T> {
        /**
         * @see _.keyBy
         */
        keyBy(
            iteratee?: ListIterator<T, any>,
            thisArg?: any
        ): LoDashExplicitObjectWrapper<Dictionary<T>>;

        /**
         * @see _.keyBy
         */
        keyBy(
            iteratee?: string,
            thisArg?: any
        ): LoDashExplicitObjectWrapper<Dictionary<T>>;

        /**
         * @see _.keyBy
         */
        keyBy<W extends Object>(
            iteratee?: W
        ): LoDashExplicitObjectWrapper<Dictionary<T>>;
    }


interface LoDashExplicitObjectWrapper<T> {
        /**
         * @see _.keyBy
         */
        keyBy<T>(
            iteratee?: ListIterator<T, any>|NumericDictionaryIterator<T, any>|DictionaryIterator<T, any>,
            thisArg?: any
        ): LoDashExplicitObjectWrapper<Dictionary<T>>;

        /**
         * @see _.keyBy
         */
        keyBy<T>(
            iteratee?: string,
            thisArg?: any
        ): LoDashExplicitObjectWrapper<Dictionary<T>>;

        /**
         * @see _.keyBy
         */
        keyBy<W extends Object, T>(
            iteratee?: W
        ): LoDashExplicitObjectWrapper<Dictionary<T>>;

        /**
         * @see _.keyBy
         */
        keyBy<T>(
            iteratee?: Object
        ): LoDashExplicitObjectWrapper<Dictionary<T>>;
    }


//_.invoke
interface LoDashStatic {
        /**
        * Invokes the method at path of object.
        * @param object The object to query.
        * @param path The path of the method to invoke.
        * @param args The arguments to invoke the method with.
        **/
        invoke<TObject extends Object, TResult>(
            object: TObject,
            path: StringRepresentable|StringRepresentable[],
            ...args: any[]): TResult;

        /**
        * @see _.invoke
        **/
        invoke<TValue, TResult>(
            object: Dictionary<TValue>|TValue[],
            path: StringRepresentable|StringRepresentable[],
            ...args: any[]): TResult;

        /**
        * @see _.invoke
        **/
        invoke<TResult>(
            object: any,
            path: StringRepresentable|StringRepresentable[],
            ...args: any[]): TResult;
    }


interface LoDashImplicitArrayWrapper<T> {
        /**
        * @see _.invoke
        **/
        invoke<TResult>(
            path: StringRepresentable|StringRepresentable[],
            ...args: any[]): TResult;
    }


interface LoDashImplicitObjectWrapper<T> {
        /**
        * @see _.invoke
        **/
        invoke<TResult>(
            path: StringRepresentable|StringRepresentable[],
            ...args: any[]): TResult;
    }


interface LoDashExplicitArrayWrapper<T> {
        /**
        * @see _.invoke
        **/
        invoke<TResult>(
            path: StringRepresentable|StringRepresentable[],
            ...args: any[]): TResult;
    }


interface LoDashExplicitObjectWrapper<T> {
        /**
        * @see _.invoke
        **/
        invoke<TResult>(
            path: StringRepresentable|StringRepresentable[],
            ...args: any[]): TResult;
    }


//_.invokeMap
interface LoDashStatic {
        /**
        * Invokes the method named by methodName on each element in the collection returning
        * an array of the results of each invoked method. Additional arguments will be provided
        * to each invoked method. If methodName is a function it will be invoked for, and this
        * bound to, each element in the collection.
        * @param collection The collection to iterate over.
        * @param methodName The name of the method to invoke.
        * @param args Arguments to invoke the method with.
        **/
        invokeMap<TValue extends {}, TResult>(
            collection: TValue[],
            methodName: string,
            ...args: any[]): TResult[];

        /**
        * @see _.invokeMap
        **/
        invokeMap<TValue extends {}, TResult>(
            collection: Dictionary<TValue>,
            methodName: string,
            ...args: any[]): TResult[];

        /**
        * @see _.invokeMap
        **/
        invokeMap<TResult>(
            collection: {}[],
            methodName: string,
            ...args: any[]): TResult[];

        /**
        * @see _.invokeMap
        **/
        invokeMap<TResult>(
            collection: Dictionary<{}>,
            methodName: string,
            ...args: any[]): TResult[];

        /**
        * @see _.invokeMap
        **/
        invokeMap<TValue extends {}, TResult>(
            collection: TValue[],
            method: (...args: any[]) => TResult,
            ...args: any[]): TResult[];

        /**
        * @see _.invokeMap
        **/
        invokeMap<TValue extends {}, TResult>(
            collection: Dictionary<TValue>,
            method: (...args: any[]) => TResult,
            ...args: any[]): TResult[];

        /**
        * @see _.invokeMap
        **/
        invokeMap<TResult>(
            collection: {}[],
            method: (...args: any[]) => TResult,
            ...args: any[]): TResult[];

        /**
        * @see _.invokeMap
        **/
        invokeMap<TResult>(
            collection: Dictionary<{}>,
            method: (...args: any[]) => TResult,
            ...args: any[]): TResult[];
    }


interface LoDashImplicitArrayWrapper<T> {
        /**
        * @see _.invokeMap
        **/
        invokeMap<TResult>(
            methodName: string,
            ...args: any[]): LoDashImplicitArrayWrapper<TResult>;

        /**
        * @see _.invokeMap
        **/
        invokeMap<TResult>(
            method: (...args: any[]) => TResult,
            ...args: any[]): LoDashImplicitArrayWrapper<TResult>;
    }


interface LoDashImplicitObjectWrapper<T> {
        /**
        * @see _.invokeMap
        **/
        invokeMap<TResult>(
            methodName: string,
            ...args: any[]): LoDashImplicitArrayWrapper<TResult>;

        /**
        * @see _.invokeMap
        **/
        invokeMap<TResult>(
            method: (...args: any[]) => TResult,
            ...args: any[]): LoDashImplicitArrayWrapper<TResult>;
    }


interface LoDashExplicitArrayWrapper<T> {
        /**
        * @see _.invokeMap
        **/
        invokeMap<TResult>(
            methodName: string,
            ...args: any[]): LoDashExplicitArrayWrapper<TResult>;

        /**
        * @see _.invokeMap
        **/
        invokeMap<TResult>(
            method: (...args: any[]) => TResult,
            ...args: any[]): LoDashExplicitArrayWrapper<TResult>;
    }


interface LoDashExplicitObjectWrapper<T> {
        /**
        * @see _.invokeMap
        **/
        invokeMap<TResult>(
            methodName: string,
            ...args: any[]): LoDashExplicitArrayWrapper<TResult>;

        /**
        * @see _.invokeMap
        **/
        invokeMap<TResult>(
            method: (...args: any[]) => TResult,
            ...args: any[]): LoDashExplicitArrayWrapper<TResult>;
    }


//_.map
interface LoDashStatic {
        /**
         * Creates an array of values by running each element in collection through iteratee. The iteratee is bound to
         * thisArg and invoked with three arguments: (value, index|key, collection).
         *
         * If a property name is provided for iteratee the created _.property style callback returns the property value
         * of the given element.
         *
         * If a value is also provided for thisArg the created _.matchesProperty style callback returns true for
         * elements that have a matching property value, else false.
         *
         * If an object is provided for iteratee the created _.matches style callback returns true for elements that
         * have the properties of the given object, else false.
         *
         * Many lodash methods are guarded to work as iteratees for methods like _.every, _.filter, _.map, _.mapValues,
         * _.reject, and _.some.
         *
         * The guarded methods are:
         * ary, callback, chunk, clone, create, curry, curryRight, drop, dropRight, every, fill, flatten, invert, max,
         * min, parseInt, slice, sortBy, take, takeRight, template, trim, trimLeft, trimRight, trunc, random, range,
         * sample, some, sum, uniq, and words
         *
         * @param collection The collection to iterate over.
         * @param iteratee The function invoked per iteration.
         * @param thisArg The this binding of iteratee.
         * @return Returns the new mapped array.
         */
        map<T, TResult>(
            collection: List<T>,
            iteratee?: ListIterator<T, TResult>,
            thisArg?: any
        ): TResult[];

        /**
         * @see _.map
         */
        map<T extends {}, TResult>(
            collection: Dictionary<T>,
            iteratee?: DictionaryIterator<T, TResult>,
            thisArg?: any
        ): TResult[];

        map<T extends {}, TResult>(
            collection: NumericDictionary<T>,
            iteratee?: NumericDictionaryIterator<T, TResult>,
            thisArg?: any
        ): TResult[];

        /**
         * @see _.map
         */
        map<T, TResult>(
            collection: List<T>|Dictionary<T>|NumericDictionary<T>,
            iteratee?: string
        ): TResult[];

        /**
         * @see _.map
         */
        map<T, TObject extends {}>(
            collection: List<T>|Dictionary<T>|NumericDictionary<T>,
            iteratee?: TObject
        ): boolean[];
    }


interface LoDashImplicitArrayWrapper<T> {
        /**
         * @see _.map
         */
        map<TResult>(
            iteratee?: ListIterator<T, TResult>,
            thisArg?: any
        ): LoDashImplicitArrayWrapper<TResult>;

        /**
         * @see _.map
         */
        map<TResult>(
            iteratee?: string
        ): LoDashImplicitArrayWrapper<TResult>;

        /**
         * @see _.map
         */
        map<TObject extends {}>(
            iteratee?: TObject
        ): LoDashImplicitArrayWrapper<boolean>;
    }


interface LoDashImplicitObjectWrapper<T> {
        /**
         * @see _.map
         */
        map<TValue, TResult>(
            iteratee?: ListIterator<TValue, TResult>|DictionaryIterator<TValue, TResult>,
            thisArg?: any
        ): LoDashImplicitArrayWrapper<TResult>;

        /**
         * @see _.map
         */
        map<TValue, TResult>(
            iteratee?: string
        ): LoDashImplicitArrayWrapper<TResult>;

        /**
         * @see _.map
         */
        map<TObject extends {}>(
            iteratee?: TObject
        ): LoDashImplicitArrayWrapper<boolean>;
    }


interface LoDashExplicitArrayWrapper<T> {
        /**
         * @see _.map
         */
        map<TResult>(
            iteratee?: ListIterator<T, TResult>,
            thisArg?: any
        ): LoDashExplicitArrayWrapper<TResult>;

        /**
         * @see _.map
         */
        map<TResult>(
            iteratee?: string
        ): LoDashExplicitArrayWrapper<TResult>;

        /**
         * @see _.map
         */
        map<TObject extends {}>(
            iteratee?: TObject
        ): LoDashExplicitArrayWrapper<boolean>;
    }


interface LoDashExplicitObjectWrapper<T> {
        /**
         * @see _.map
         */
        map<TValue, TResult>(
            iteratee?: ListIterator<TValue, TResult>|DictionaryIterator<TValue, TResult>,
            thisArg?: any
        ): LoDashExplicitArrayWrapper<TResult>;

        /**
         * @see _.map
         */
        map<TValue, TResult>(
            iteratee?: string
        ): LoDashExplicitArrayWrapper<TResult>;

        /**
         * @see _.map
         */
        map<TObject extends {}>(
            iteratee?: TObject
        ): LoDashExplicitArrayWrapper<boolean>;
    }


//_.partition
interface LoDashStatic {
        /**
        * Creates an array of elements split into two groups, the first of which contains elements predicate returns truthy for,
        * while the second of which contains elements predicate returns falsey for.
        * The predicate is bound to thisArg and invoked with three arguments: (value, index|key, collection).
        *
        * If a property name is provided for predicate the created _.property style callback
        * returns the property value of the given element.
        *
        * If a value is also provided for thisArg the created _.matchesProperty style callback
        * returns true for elements that have a matching property value, else false.
        *
        * If an object is provided for predicate the created _.matches style callback returns
        * true for elements that have the properties of the given object, else false.
        *
        * @param collection The collection to iterate over.
        * @param callback The function called per iteration.
        * @param thisArg The this binding of predicate.
        * @return Returns the array of grouped elements.
        **/
        partition<T>(
            collection: List<T>,
            callback: ListIterator<T, boolean>,
            thisArg?: any): T[][];

        /**
         * @see _.partition
         **/
        partition<T>(
            collection: Dictionary<T>,
            callback: DictionaryIterator<T, boolean>,
            thisArg?: any): T[][];

        /**
         * @see _.partition
         **/
        partition<W, T>(
            collection: List<T>,
            whereValue: W): T[][];

        /**
         * @see _.partition
         **/
        partition<W, T>(
            collection: Dictionary<T>,
            whereValue: W): T[][];

        /**
         * @see _.partition
         **/
        partition<T>(
            collection: List<T>,
            path: string,
            srcValue: any): T[][];

        /**
         * @see _.partition
         **/
        partition<T>(
            collection: Dictionary<T>,
            path: string,
            srcValue: any): T[][];

        /**
         * @see _.partition
         **/
        partition<T>(
            collection: List<T>,
            pluckValue: string): T[][];

        /**
         * @see _.partition
         **/
        partition<T>(
            collection: Dictionary<T>,
            pluckValue: string): T[][];
    }


interface LoDashImplicitStringWrapper {
        /**
         * @see _.partition
         */
        partition(
            callback: ListIterator<string, boolean>,
            thisArg?: any): LoDashImplicitArrayWrapper<string[]>;
    }


interface LoDashImplicitArrayWrapper<T> {
        /**
         * @see _.partition
         */
        partition(
            callback: ListIterator<T, boolean>,
            thisArg?: any): LoDashImplicitArrayWrapper<T[]>;
        /**
         * @see _.partition
         */
        partition<W>(
            whereValue: W): LoDashImplicitArrayWrapper<T[]>;
        /**
         * @see _.partition
         */
        partition(
            path: string,
            srcValue: any): LoDashImplicitArrayWrapper<T[]>;
        /**
         * @see _.partition
         */
        partition(
            pluckValue: string): LoDashImplicitArrayWrapper<T[]>;
    }


interface LoDashImplicitObjectWrapper<T> {
        /**
         * @see _.partition
         */
        partition<TResult>(
            callback: ListIterator<TResult, boolean>,
            thisArg?: any): LoDashImplicitArrayWrapper<TResult[]>;

        /**
         * @see _.partition
         */
        partition<TResult>(
            callback: DictionaryIterator<TResult, boolean>,
            thisArg?: any): LoDashImplicitArrayWrapper<TResult[]>;

        /**
         * @see _.partition
         */
        partition<W, TResult>(
            whereValue: W): LoDashImplicitArrayWrapper<TResult[]>;

        /**
         * @see _.partition
         */
        partition<TResult>(
            path: string,
            srcValue: any): LoDashImplicitArrayWrapper<TResult[]>;

        /**
         * @see _.partition
         */
        partition<TResult>(
            pluckValue: string): LoDashImplicitArrayWrapper<TResult[]>;
    }


//_.reduce
interface LoDashStatic {
        /**
        * Reduces a collection to a value which is the accumulated result of running each
        * element in the collection through the callback, where each successive callback execution
        * consumes the return value of the previous execution. If accumulator is not provided the
        * first element of the collection will be used as the initial accumulator value. The callback
        * is bound to thisArg and invoked with four arguments; (accumulator, value, index|key, collection).
        * @param collection The collection to iterate over.
        * @param callback The function called per iteration.
        * @param accumulator Initial value of the accumulator.
        * @param thisArg The this binding of callback.
        * @return Returns the accumulated value.
        **/
        reduce<T, TResult>(
            collection: Array<T>,
            callback: MemoIterator<T, TResult>,
            accumulator: TResult,
            thisArg?: any): TResult;

        /**
        * @see _.reduce
        **/
        reduce<T, TResult>(
            collection: List<T>,
            callback: MemoIterator<T, TResult>,
            accumulator: TResult,
            thisArg?: any): TResult;

        /**
        * @see _.reduce
        **/
        reduce<T, TResult>(
            collection: Dictionary<T>,
            callback: MemoIterator<T, TResult>,
            accumulator: TResult,
            thisArg?: any): TResult;

        /**
        * @see _.reduce
        **/
        reduce<T, TResult>(
            collection: NumericDictionary<T>,
            callback: MemoIterator<T, TResult>,
            accumulator: TResult,
            thisArg?: any): TResult;

        /**
        * @see _.reduce
        **/
        reduce<T, TResult>(
            collection: Array<T>,
            callback: MemoIterator<T, TResult>,
            thisArg?: any): TResult;

        /**
        * @see _.reduce
        **/
        reduce<T, TResult>(
            collection: List<T>,
            callback: MemoIterator<T, TResult>,
            thisArg?: any): TResult;

        /**
        * @see _.reduce
        **/
        reduce<T, TResult>(
            collection: Dictionary<T>,
            callback: MemoIterator<T, TResult>,
            thisArg?: any): TResult;

        /**
        * @see _.reduce
        **/
        reduce<T, TResult>(
            collection: NumericDictionary<T>,
            callback: MemoIterator<T, TResult>,
            thisArg?: any): TResult;

    }


interface LoDashImplicitArrayWrapper<T> {
         /**
        * @see _.reduce
        **/
        reduce<TResult>(
            callback: MemoIterator<T, TResult>,
            accumulator: TResult,
            thisArg?: any): TResult;

        /**
        * @see _.reduce
        **/
        reduce<TResult>(
            callback: MemoIterator<T, TResult>,
            thisArg?: any): TResult;
    }


interface LoDashImplicitObjectWrapper<T> {
         /**
        * @see _.reduce
        **/
        reduce<TValue, TResult>(
            callback: MemoIterator<TValue, TResult>,
            accumulator: TResult,
            thisArg?: any): TResult;

        /**
        * @see _.reduce
        **/
        reduce<TValue, TResult>(
            callback: MemoIterator<TValue, TResult>,
            thisArg?: any): TResult;
    }


//_.reduceRight
interface LoDashStatic {
        /**
        * This method is like _.reduce except that it iterates over elements of a collection from
        * right to left.
        * @param collection The collection to iterate over.
        * @param callback The function called per iteration.
        * @param accumulator Initial value of the accumulator.
        * @param thisArg The this binding of callback.
        * @return The accumulated value.
        **/
        reduceRight<T, TResult>(
            collection: Array<T>,
            callback: MemoIterator<T, TResult>,
            accumulator: TResult,
            thisArg?: any): TResult;

        /**
        * @see _.reduceRight
        **/
        reduceRight<T, TResult>(
            collection: List<T>,
            callback: MemoIterator<T, TResult>,
            accumulator: TResult,
            thisArg?: any): TResult;

        /**
        * @see _.reduceRight
        **/
        reduceRight<T, TResult>(
            collection: Dictionary<T>,
            callback: MemoIterator<T, TResult>,
            accumulator: TResult,
            thisArg?: any): TResult;

        /**
        * @see _.reduceRight
        **/
        reduceRight<T, TResult>(
            collection: Array<T>,
            callback: MemoIterator<T, TResult>,
            thisArg?: any): TResult;

        /**
        * @see _.reduceRight
        **/
        reduceRight<T, TResult>(
            collection: List<T>,
            callback: MemoIterator<T, TResult>,
            thisArg?: any): TResult;

        /**
        * @see _.reduceRight
        **/
        reduceRight<T, TResult>(
            collection: Dictionary<T>,
            callback: MemoIterator<T, TResult>,
            thisArg?: any): TResult;
    }


//_.reject
interface LoDashStatic {
        /**
         * The opposite of _.filter; this method returns the elements of collection that predicate does not return
         * truthy for.
         *
         * @param collection The collection to iterate over.
         * @param predicate The function invoked per iteration.
         * @param thisArg The this binding of predicate.
         * @return Returns the new filtered array.
         */
        reject<T>(
            collection: List<T>,
            predicate?: ListIterator<T, boolean>,
            thisArg?: any
        ): T[];

        /**
         * @see _.reject
         */
        reject<T>(
            collection: Dictionary<T>,
            predicate?: DictionaryIterator<T, boolean>,
            thisArg?: any
        ): T[];

        /**
         * @see _.reject
         */
        reject(
            collection: string,
            predicate?: StringIterator<boolean>,
            thisArg?: any
        ): string[];

        /**
         * @see _.reject
         */
        reject<T>(
            collection: List<T>|Dictionary<T>,
            predicate: string,
            thisArg?: any
        ): T[];

        /**
         * @see _.reject
         */
        reject<W extends {}, T>(
            collection: List<T>|Dictionary<T>,
            predicate: W
        ): T[];
    }


interface LoDashImplicitWrapper<T> {
        /**
         * @see _.reject
         */
        reject(
            predicate?: StringIterator<boolean>,
            thisArg?: any
        ): LoDashImplicitArrayWrapper<string>;
    }


interface LoDashImplicitArrayWrapper<T> {
        /**
         * @see _.reject
         */
        reject(
            predicate: ListIterator<T, boolean>,
            thisArg?: any
        ): LoDashImplicitArrayWrapper<T>;

        /**
         * @see _.reject
         */
        reject(
            predicate: string,
            thisArg?: any
        ): LoDashImplicitArrayWrapper<T>;

        /**
         * @see _.reject
         */
        reject<W>(predicate: W): LoDashImplicitArrayWrapper<T>;
    }


interface LoDashImplicitObjectWrapper<T> {
        /**
         * @see _.reject
         */
        reject<T>(
            predicate: ListIterator<T, boolean>|DictionaryIterator<T, boolean>,
            thisArg?: any
        ): LoDashImplicitArrayWrapper<T>;

        /**
         * @see _.reject
         */
        reject<T>(
            predicate: string,
            thisArg?: any
        ): LoDashImplicitArrayWrapper<T>;

        /**
         * @see _.reject
         */
        reject<W, T>(predicate: W): LoDashImplicitArrayWrapper<T>;
    }


interface LoDashExplicitWrapper<T> {
        /**
         * @see _.reject
         */
        reject(
            predicate?: StringIterator<boolean>,
            thisArg?: any
        ): LoDashExplicitArrayWrapper<string>;
    }


interface LoDashExplicitArrayWrapper<T> {
        /**
         * @see _.reject
         */
        reject(
            predicate: ListIterator<T, boolean>,
            thisArg?: any
        ): LoDashExplicitArrayWrapper<T>;

        /**
         * @see _.reject
         */
        reject(
            predicate: string,
            thisArg?: any
        ): LoDashExplicitArrayWrapper<T>;

        /**
         * @see _.reject
         */
        reject<W>(predicate: W): LoDashExplicitArrayWrapper<T>;
    }


interface LoDashExplicitObjectWrapper<T> {
        /**
         * @see _.reject
         */
        reject<T>(
            predicate: ListIterator<T, boolean>|DictionaryIterator<T, boolean>,
            thisArg?: any
        ): LoDashExplicitArrayWrapper<T>;

        /**
         * @see _.reject
         */
        reject<T>(
            predicate: string,
            thisArg?: any
        ): LoDashExplicitArrayWrapper<T>;

        /**
         * @see _.reject
         */
        reject<W, T>(predicate: W): LoDashExplicitArrayWrapper<T>;
    }


//_.sample
interface LoDashStatic {
        /**
         * Gets a random element from `collection`.
         *
         * @static
         * @memberOf _
         * @category Collection
         * @param {Array|Object} collection The collection to sample.
         * @returns {*} Returns the random element.
         * @example
         *
         * _.sample([1, 2, 3, 4]);
         * // => 2
         */
        sample<T>(collection: Array<T>): T;

        /**
        * @see _.sample
        **/
        sample<T>(collection: List<T>): T;

        /**
        * @see _.sample
        **/
        sample<T>(collection: Dictionary<T>): T;
    }


interface LoDashImplicitArrayWrapper<T> {
        /**
         * @see _.sample
         **/
        sample(): LoDashImplicitWrapper<T>;
    }


//_.sampleSize
interface LoDashStatic {
        /**
         * Gets `n` random elements from `collection`.
         *
         * @static
         * @memberOf _
         * @category Collection
         * @param {Array|Object} collection The collection to sample.
         * @param {number} [n=0] The number of elements to sample.
         * @returns {Array} Returns the random elements.
         * @example
         *
         * _.sampleSize([1, 2, 3, 4], 2);
         * // => [3, 1]
         */
        sampleSize<T>(collection: Array<T>, n: number): T[];

        /**
        * @see _.sampleSize
        **/
        sampleSize<T>(collection: List<T>, n: number): T[];

        /**
        * @see _.sampleSize
        **/
        sampleSize<T>(collection: Dictionary<T>, n: number): T[];
    }


interface LoDashImplicitArrayWrapper<T> {
        /**
         * @see _.sampleSize
         **/
        sampleSize(n: number): LoDashImplicitArrayWrapper<T>;

        /**
         * @see _.sampleSize
         **/
        sampleSize(): LoDashImplicitWrapper<T>;
    }


//_.shuffle
interface LoDashStatic {
        /**
         * Creates an array of shuffled values, using a version of the Fisher-Yates shuffle.
         *
         * @param collection The collection to shuffle.
         * @return Returns the new shuffled array.
         */
        shuffle<T>(collection: List<T>|Dictionary<T>): T[];

        /**
         * @see _.shuffle
         */
        shuffle(collection: string): string[];
    }


interface LoDashImplicitWrapper<T> {
        /**
         * @see _.shuffle
         */
        shuffle(): LoDashImplicitArrayWrapper<string>;
    }


interface LoDashImplicitArrayWrapper<T> {
        /**
         * @see _.shuffle
         */
        shuffle(): LoDashImplicitArrayWrapper<T>;
    }


interface LoDashImplicitObjectWrapper<T> {
        /**
         * @see _.shuffle
         */
        shuffle<T>(): LoDashImplicitArrayWrapper<T>;
    }


interface LoDashExplicitWrapper<T> {
        /**
         * @see _.shuffle
         */
        shuffle(): LoDashExplicitArrayWrapper<string>;
    }


interface LoDashExplicitArrayWrapper<T> {
        /**
         * @see _.shuffle
         */
        shuffle(): LoDashExplicitArrayWrapper<T>;
    }


interface LoDashExplicitObjectWrapper<T> {
        /**
         * @see _.shuffle
         */
        shuffle<T>(): LoDashExplicitArrayWrapper<T>;
    }


//_.size
interface LoDashStatic {
        /**
         * Gets the size of collection by returning its length for array-like values or the number of own enumerable
         * properties for objects.
         *
         * @param collection The collection to inspect.
         * @return Returns the size of collection.
         */
        size<T>(collection: List<T>|Dictionary<T>): number;

        /**
         * @see _.size
         */
        size(collection: string): number;
    }


interface LoDashImplicitWrapper<T> {
        /**
         * @see _.size
         */
        size(): number;
    }


interface LoDashImplicitArrayWrapper<T> {
        /**
         * @see _.size
         */
        size(): number;
    }


interface LoDashImplicitObjectWrapper<T> {
        /**
         * @see _.size
         */
        size(): number;
    }


interface LoDashExplicitWrapper<T> {
        /**
         * @see _.size
         */
        size(): LoDashExplicitWrapper<number>;
    }


interface LoDashExplicitArrayWrapper<T> {
        /**
         * @see _.size
         */
        size(): LoDashExplicitWrapper<number>;
    }


interface LoDashExplicitObjectWrapper<T> {
        /**
         * @see _.size
         */
        size(): LoDashExplicitWrapper<number>;
    }


//_.some
interface LoDashStatic {
        /**
         * Checks if predicate returns truthy for any element of collection. Iteration is stopped once predicate
         * returns truthy. The predicate is invoked with three arguments: (value, index|key, collection).
         *
         * @param collection The collection to iterate over.
         * @param predicate The function invoked per iteration.
         * @return Returns true if any element passes the predicate check, else false.
         */
        some<T>(
            collection: List<T>,
            predicate?: ListIterator<T, boolean>
        ): boolean;

        /**
         * @see _.some
         */
        some<T>(
            collection: Dictionary<T>,
            predicate?: DictionaryIterator<T, boolean>
        ): boolean;

        /**
         * @see _.some
         */
        some<T>(
            collection: NumericDictionary<T>,
            predicate?: NumericDictionaryIterator<T, boolean>
        ): boolean;

        /**
         * @see _.some
         */
        some(
            collection: Object,
            predicate?: ObjectIterator<any, boolean>
        ): boolean;

        /**
         * @see _.some
         */
        some<T>(
            collection: List<T>|Dictionary<T>|NumericDictionary<T>,
            predicate?: string|[string, any]
        ): boolean;

        /**
         * @see _.some
         */
        some(
            collection: Object,
            predicate?: string|[string, any]
        ): boolean;

        /**
         * @see _.some
         */
        some<TObject extends {}, T>(
            collection: List<T>|Dictionary<T>|NumericDictionary<T>,
            predicate?: TObject
        ): boolean;

        /**
         * @see _.some
         */
        some<T>(
            collection: List<T>|Dictionary<T>|NumericDictionary<T>,
            predicate?: Object
        ): boolean;

        /**
         * @see _.some
         */
        some<TObject extends {}>(
            collection: Object,
            predicate?: TObject
        ): boolean;
    }


interface LoDashImplicitArrayWrapper<T> {
        /**
         * @see _.some
         */
        some(
            predicate?: ListIterator<T, boolean>|NumericDictionaryIterator<T, boolean>
        ): boolean;

        /**
         * @see _.some
         */
        some(
            predicate?: string|[string, any]
        ): boolean;

        /**
         * @see _.some
         */
        some<TObject extends {}>(
            predicate?: TObject
        ): boolean;
    }


interface LoDashImplicitObjectWrapper<T> {
        /**
         * @see _.some
         */
        some<TResult>(
            predicate?: ListIterator<TResult, boolean>|DictionaryIterator<TResult, boolean>|NumericDictionaryIterator<T, boolean>|ObjectIterator<any, boolean>
        ): boolean;

        /**
         * @see _.some
         */
        some(
            predicate?: string|[string, any]
        ): boolean;

        /**
         * @see _.some
         */
        some<TObject extends {}>(
            predicate?: TObject
        ): boolean;
    }


interface LoDashExplicitArrayWrapper<T> {
        /**
         * @see _.some
         */
        some(
            predicate?: ListIterator<T, boolean>|NumericDictionaryIterator<T, boolean>
        ): LoDashExplicitWrapper<boolean>;

        /**
         * @see _.some
         */
        some(
            predicate?: string|[string, any]
        ): LoDashExplicitWrapper<boolean>;

        /**
         * @see _.some
         */
        some<TObject extends {}>(
            predicate?: TObject
        ): LoDashExplicitWrapper<boolean>;
    }


interface LoDashExplicitObjectWrapper<T> {
        /**
         * @see _.some
         */
        some<TResult>(
            predicate?: ListIterator<TResult, boolean>|DictionaryIterator<TResult, boolean>|NumericDictionaryIterator<T, boolean>|ObjectIterator<any, boolean>
        ): LoDashExplicitWrapper<boolean>;

        /**
         * @see _.some
         */
        some(
            predicate?: string|[string, any]
        ): LoDashExplicitWrapper<boolean>;

        /**
         * @see _.some
         */
        some<TObject extends {}>(
            predicate?: TObject
        ): LoDashExplicitWrapper<boolean>;
    }


//_.sortBy
interface LoDashStatic {
        /**
         * Creates an array of elements, sorted in ascending order by the results of
         * running each element in a collection through each iteratee. This method
         * performs a stable sort, that is, it preserves the original sort order of
         * equal elements. The iteratees are invoked with one argument: (value).
         *
         * @static
         * @memberOf _
         * @category Collection
         * @param {Array|Object} collection The collection to iterate over.
         * @param {...(Function|Function[]|Object|Object[]|string|string[])} [iteratees=[_.identity]]
         *  The iteratees to sort by, specified individually or in arrays.
         * @returns {Array} Returns the new sorted array.
         * @example
         *
         * var users = [
         *   { 'user': 'fred',   'age': 48 },
         *   { 'user': 'barney', 'age': 36 },
         *   { 'user': 'fred',   'age': 42 },
         *   { 'user': 'barney', 'age': 34 }
         * ];
         *
         * _.sortBy(users, function(o) { return o.user; });
         * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 42]]
         *
         * _.sortBy(users, ['user', 'age']);
         * // => objects for [['barney', 34], ['barney', 36], ['fred', 42], ['fred', 48]]
         *
         * _.sortBy(users, 'user', function(o) {
         *   return Math.floor(o.age / 10);
         * });
         * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 42]]
         */
        sortBy<T, TSort>(
            collection: List<T>,
            iteratee?: ListIterator<T, TSort>
        ): T[];

        /**
         * @see _.sortBy
         */
        sortBy<T, TSort>(
            collection: Dictionary<T>,
            iteratee?: DictionaryIterator<T, TSort>
        ): T[];

        /**
         * @see _.sortBy
         */
        sortBy<T>(
            collection: List<T>|Dictionary<T>,
            iteratee: string
        ): T[];

        /**
         * @see _.sortBy
         */
        sortBy<W extends {}, T>(
            collection: List<T>|Dictionary<T>,
            whereValue: W
        ): T[];

        /**
         * @see _.sortBy
         */
        sortBy<T>(
            collection: List<T>|Dictionary<T>
        ): T[];

        /**
         * @see _.sortBy
         */
        sortBy<T>(
            collection: (Array<T>|List<T>),
            iteratees: (ListIterator<T, any>|string|Object)[]): T[];

        /**
         * @see _.sortBy
         */
        sortBy<T>(
            collection: (Array<T>|List<T>),
            ...iteratees: (ListIterator<T, boolean>|Object|string)[]): T[];
    }


interface LoDashImplicitArrayWrapper<T> {
        /**
         * @see _.sortBy
         */
        sortBy<TSort>(
            iteratee?: ListIterator<T, TSort>
        ): LoDashImplicitArrayWrapper<T>;

        /**
         * @see _.sortBy
         */
        sortBy(iteratee: string): LoDashImplicitArrayWrapper<T>;

        /**
         * @see _.sortBy
         */
        sortBy<W extends {}>(whereValue: W): LoDashImplicitArrayWrapper<T>;

        /**
         * @see _.sortBy
         */
        sortBy(): LoDashImplicitArrayWrapper<T>;

        /**
         * @see _.sortBy
         */
        sortBy(...iteratees: (ListIterator<T, boolean>|Object|string)[]): LoDashImplicitArrayWrapper<T>;

        /**
        * @see _.sortBy
        **/
        sortBy(iteratees: (ListIterator<T, any>|string|Object)[]): LoDashImplicitArrayWrapper<T>;
    }


interface LoDashImplicitObjectWrapper<T> {
        /**
         * @see _.sortBy
         */
        sortBy<T, TSort>(
            iteratee?: ListIterator<T, TSort>|DictionaryIterator<T, TSort>
        ): LoDashImplicitArrayWrapper<T>;

        /**
         * @see _.sortBy
         */
        sortBy<T>(iteratee: string): LoDashImplicitArrayWrapper<T>;

        /**
         * @see _.sortBy
         */
        sortBy<W extends {}, T>(whereValue: W): LoDashImplicitArrayWrapper<T>;

        /**
         * @see _.sortBy
         */
        sortBy<T>(): LoDashImplicitArrayWrapper<T>;
    }


interface LoDashExplicitArrayWrapper<T> {
        /**
         * @see _.sortBy
         */
        sortBy<TSort>(
            iteratee?: ListIterator<T, TSort>
        ): LoDashExplicitArrayWrapper<T>;

        /**
         * @see _.sortBy
         */
        sortBy(iteratee: string): LoDashExplicitArrayWrapper<T>;

        /**
         * @see _.sortBy
         */
        sortBy<W extends {}>(whereValue: W): LoDashExplicitArrayWrapper<T>;

        /**
         * @see _.sortBy
         */
        sortBy(): LoDashExplicitArrayWrapper<T>;
    }


interface LoDashExplicitObjectWrapper<T> {
        /**
         * @see _.sortBy
         */
        sortBy<T, TSort>(
            iteratee?: ListIterator<T, TSort>|DictionaryIterator<T, TSort>
        ): LoDashExplicitArrayWrapper<T>;

        /**
         * @see _.sortBy
         */
        sortBy<T>(iteratee: string): LoDashExplicitArrayWrapper<T>;

        /**
         * @see _.sortBy
         */
        sortBy<W extends {}, T>(whereValue: W): LoDashExplicitArrayWrapper<T>;

        /**
         * @see _.sortBy
         */
        sortBy<T>(): LoDashExplicitArrayWrapper<T>;
    }


//_.orderBy
interface LoDashStatic {
        /**
         * This method is like `_.sortBy` except that it allows specifying the sort
         * orders of the iteratees to sort by. If `orders` is unspecified, all values
         * are sorted in ascending order. Otherwise, specify an order of "desc" for
         * descending or "asc" for ascending sort order of corresponding values.
         *
         * @static
         * @memberOf _
         * @category Collection
         * @param {Array|Object} collection The collection to iterate over.
         * @param {Function[]|Object[]|string[]} [iteratees=[_.identity]] The iteratees to sort by.
         * @param {string[]} [orders] The sort orders of `iteratees`.
         * @param- {Object} [guard] Enables use as an iteratee for functions like `_.reduce`.
         * @returns {Array} Returns the new sorted array.
         * @example
         *
         * var users = [
         *   { 'user': 'fred',   'age': 48 },
         *   { 'user': 'barney', 'age': 34 },
         *   { 'user': 'fred',   'age': 42 },
         *   { 'user': 'barney', 'age': 36 }
         * ];
         *
         * // sort by `user` in ascending order and by `age` in descending order
         * _.orderBy(users, ['user', 'age'], ['asc', 'desc']);
         * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 42]]
         */
        orderBy<W extends Object, T>(
            collection: List<T>,
            iteratees: ListIterator<T, any>|string|W|(ListIterator<T, any>|string|W)[],
            orders?: boolean|string|(boolean|string)[]
        ): T[];

        /**
         * @see _.orderBy
         */
        orderBy<T>(
            collection: List<T>,
            iteratees: ListIterator<T, any>|string|Object|(ListIterator<T, any>|string|Object)[],
            orders?: boolean|string|(boolean|string)[]
        ): T[];

        /**
         * @see _.orderBy
         */
        orderBy<W extends Object, T>(
            collection: NumericDictionary<T>,
            iteratees: NumericDictionaryIterator<T, any>|string|W|(NumericDictionaryIterator<T, any>|string|W)[],
            orders?: boolean|string|(boolean|string)[]
        ): T[];

        /**
         * @see _.orderBy
         */
        orderBy<T>(
            collection: NumericDictionary<T>,
            iteratees: NumericDictionaryIterator<T, any>|string|Object|(NumericDictionaryIterator<T, any>|string|Object)[],
            orders?: boolean|string|(boolean|string)[]
        ): T[];

        /**
         * @see _.orderBy
         */
        orderBy<W extends Object, T>(
            collection: Dictionary<T>,
            iteratees: DictionaryIterator<T, any>|string|W|(DictionaryIterator<T, any>|string|W)[],
            orders?: boolean|string|(boolean|string)[]
        ): T[];

        /**
         * @see _.orderBy
         */
        orderBy<T>(
            collection: Dictionary<T>,
            iteratees: DictionaryIterator<T, any>|string|Object|(DictionaryIterator<T, any>|string|Object)[],
            orders?: boolean|string|(boolean|string)[]
        ): T[];
    }


interface LoDashImplicitWrapper<T> {
        /**
         * @see _.orderBy
         */
        orderBy(
            iteratees: ListIterator<T, any>|string|(ListIterator<T, any>|string)[],
            orders?: boolean|string|(boolean|string)[]
        ): LoDashImplicitArrayWrapper<T>;
    }


interface LoDashImplicitArrayWrapper<T> {
        /**
         * @see _.orderBy
         */
        orderBy<W extends Object>(
            iteratees: ListIterator<T, any>|string|W|(ListIterator<T, any>|string|W)[],
            orders?: boolean|string|(boolean|string)[]
        ): LoDashImplicitArrayWrapper<T>;
    }


interface LoDashImplicitObjectWrapper<T> {
        /**
         * @see _.orderBy
         */
        orderBy<W extends Object, T>(
            iteratees: ListIterator<T, any>|string|W|(ListIterator<T, any>|string|W)[],
            orders?: boolean|string|(boolean|string)[]
        ): LoDashImplicitArrayWrapper<T>;

        /**
         * @see _.orderBy
         */
        orderBy<T>(
            iteratees: ListIterator<T, any>|string|Object|(ListIterator<T, any>|string|Object)[],
            orders?: boolean|string|(boolean|string)[]
        ): LoDashImplicitArrayWrapper<T>;

        /**
         * @see _.orderBy
         */
        orderBy<W extends Object, T>(
            iteratees: NumericDictionaryIterator<T, any>|string|W|(NumericDictionaryIterator<T, any>|string|W)[],
            orders?: boolean|string|(boolean|string)[]
        ): LoDashImplicitArrayWrapper<T>;

        /**
         * @see _.orderBy
         */
        orderBy<T>(
            iteratees: NumericDictionaryIterator<T, any>|string|Object|(NumericDictionaryIterator<T, any>|string|Object)[],
            orders?: boolean|string|(boolean|string)[]
        ): LoDashImplicitArrayWrapper<T>;

        /**
         * @see _.orderBy
         */
        orderBy<W extends Object, T>(
            iteratees: DictionaryIterator<T, any>|string|W|(DictionaryIterator<T, any>|string|W)[],
            orders?: boolean|string|(boolean|string)[]
        ): LoDashImplicitArrayWrapper<T>;

        /**
         * @see _.orderBy
         */
        orderBy<T>(
            iteratees: DictionaryIterator<T, any>|string|Object|(DictionaryIterator<T, any>|string|Object)[],
            orders?: boolean|string|(boolean|string)[]
        ): LoDashImplicitArrayWrapper<T>;
    }


interface LoDashExplicitWrapper<T> {
        /**
         * @see _.orderBy
         */
        orderBy(
            iteratees: ListIterator<T, any>|string|(ListIterator<T, any>|string)[],
            orders?: boolean|string|(boolean|string)[]
        ): LoDashExplicitArrayWrapper<T>;
    }


interface LoDashExplicitArrayWrapper<T> {
        /**
         * @see _.orderBy
         */
        orderBy<W extends Object>(
            iteratees: ListIterator<T, any>|string|W|(ListIterator<T, any>|string|W)[],
            orders?: boolean|string|(boolean|string)[]
        ): LoDashExplicitArrayWrapper<T>;
    }


interface LoDashExplicitObjectWrapper<T> {
        /**
         * @see _.orderBy
         */
        orderBy<W extends Object, T>(
            iteratees: ListIterator<T, any>|string|W|(ListIterator<T, any>|string|W)[],
            orders?: boolean|string|(boolean|string)[]
        ): LoDashExplicitArrayWrapper<T>;

        /**
         * @see _.orderBy
         */
        orderBy<T>(
            iteratees: ListIterator<T, any>|string|Object|(ListIterator<T, any>|string|Object)[],
            orders?: boolean|string|(boolean|string)[]
        ): LoDashExplicitArrayWrapper<T>;

        /**
         * @see _.orderBy
         */
        orderBy<W extends Object, T>(
            iteratees: NumericDictionaryIterator<T, any>|string|W|(NumericDictionaryIterator<T, any>|string|W)[],
            orders?: boolean|string|(boolean|string)[]
        ): LoDashExplicitArrayWrapper<T>;

        /**
         * @see _.orderBy
         */
        orderBy<T>(
            iteratees: NumericDictionaryIterator<T, any>|string|Object|(NumericDictionaryIterator<T, any>|string|Object)[],
            orders?: boolean|string|(boolean|string)[]
        ): LoDashExplicitArrayWrapper<T>;

        /**
         * @see _.orderBy
         */
        orderBy<W extends Object, T>(
            iteratees: DictionaryIterator<T, any>|string|W|(DictionaryIterator<T, any>|string|W)[],
            orders?: boolean|string|(boolean|string)[]
        ): LoDashExplicitArrayWrapper<T>;

        /**
         * @see _.orderBy
         */
        orderBy<T>(
            iteratees: DictionaryIterator<T, any>|string|Object|(DictionaryIterator<T, any>|string|Object)[],
            orders?: boolean|string|(boolean|string)[]
        ): LoDashExplicitArrayWrapper<T>;
    }


/********
     * Date *
     ********/
//_.now
interface LoDashStatic {
        /**
         * Gets the number of milliseconds that have elapsed since the Unix epoch (1 January 1970 00:00:00 UTC).
         *
         * @return The number of milliseconds.
         */
        now(): number;
    }


interface LoDashImplicitWrapperBase<T, TWrapper> {
        /**
         * @see _.now
         */
        now(): number;
    }


interface LoDashExplicitWrapperBase<T, TWrapper> {
        /**
         * @see _.now
         */
        now(): LoDashExplicitWrapper<number>;
    }


/*************
     * Functions *
     *************/
//_.after
interface LoDashStatic {
        /**
         * The opposite of _.before; this method creates a function that invokes func once it’s called n or more times.
         *
         * @param n The number of calls before func is invoked.
         * @param func The function to restrict.
         * @return Returns the new restricted function.
         */
        after<TFunc extends Function>(
            n: number,
            func: TFunc
        ): TFunc;
    }


interface LoDashImplicitWrapper<T> {
        /**
        * @see _.after
        **/
        after<TFunc extends Function>(func: TFunc): LoDashImplicitObjectWrapper<TFunc>;
    }


interface LoDashExplicitWrapper<T> {
        /**
         * @see _.after
         **/
        after<TFunc extends Function>(func: TFunc): LoDashExplicitObjectWrapper<TFunc>;
    }


//_.ary
interface LoDashStatic {
        /**
         * Creates a function that accepts up to n arguments ignoring any additional arguments.
         *
         * @param func The function to cap arguments for.
         * @param n The arity cap.
         * @returns Returns the new function.
         */
        ary<TResult extends Function>(
            func: Function,
            n?: number
        ): TResult;

        ary<T extends Function, TResult extends Function>(
            func: T,
            n?: number
        ): TResult;
    }


interface LoDashImplicitObjectWrapper<T> {
        /**
         * @see _.ary
         */
        ary<TResult extends Function>(n?: number): LoDashImplicitObjectWrapper<TResult>;
    }


interface LoDashExplicitObjectWrapper<T> {
        /**
         * @see _.ary
         */
        ary<TResult extends Function>(n?: number): LoDashExplicitObjectWrapper<TResult>;
    }


//_.before
interface LoDashStatic {
        /**
         * Creates a function that invokes func, with the this binding and arguments of the created function, while
         * it’s called less than n times. Subsequent calls to the created function return the result of the last func
         * invocation.
         *
         * @param n The number of calls at which func is no longer invoked.
         * @param func The function to restrict.
         * @return Returns the new restricted function.
         */
        before<TFunc extends Function>(
            n: number,
            func: TFunc
        ): TFunc;
    }


interface LoDashImplicitWrapper<T> {
        /**
         * @see _.before
         **/
        before<TFunc extends Function>(func: TFunc): LoDashImplicitObjectWrapper<TFunc>;
    }


interface LoDashExplicitWrapper<T> {
        /**
         * @see _.before
         **/
        before<TFunc extends Function>(func: TFunc): LoDashExplicitObjectWrapper<TFunc>;
    }


//_.bind
interface FunctionBind {
        placeholder: any;

        <T extends Function, TResult extends Function>(
            func: T,
            thisArg: any,
            ...partials: any[]
        ): TResult;

        <TResult extends Function>(
            func: Function,
            thisArg: any,
            ...partials: any[]
        ): TResult;
    }


interface LoDashStatic {
        /**
         * Creates a function that invokes func with the this binding of thisArg and prepends any additional _.bind
         * arguments to those provided to the bound function.
         *
         * The _.bind.placeholder value, which defaults to _ in monolithic builds, may be used as a placeholder for
         * partially applied arguments.
         *
         * Note: Unlike native Function#bind this method does not set the "length" property of bound functions.
         *
         * @param func The function to bind.
         * @param thisArg The this binding of func.
         * @param partials The arguments to be partially applied.
         * @return Returns the new bound function.
         */
        bind: FunctionBind;
    }


interface LoDashImplicitObjectWrapper<T> {
        /**
         * @see _.bind
         */
        bind<TResult extends Function>(
            thisArg: any,
            ...partials: any[]
        ): LoDashImplicitObjectWrapper<TResult>;
    }


interface LoDashExplicitObjectWrapper<T> {
        /**
         * @see _.bind
         */
        bind<TResult extends Function>(
            thisArg: any,
            ...partials: any[]
        ): LoDashExplicitObjectWrapper<TResult>;
    }


//_.bindAll
interface LoDashStatic {
        /**
         * Binds methods of an object to the object itself, overwriting the existing method. Method names may be
         * specified as individual arguments or as arrays of method names. If no method names are provided all
         * enumerable function properties, own and inherited, of object are bound.
         *
         * Note: This method does not set the "length" property of bound functions.
         *
         * @param object The object to bind and assign the bound methods to.
         * @param methodNames The object method names to bind, specified as individual method names or arrays of
         * method names.
         * @return Returns object.
         */
        bindAll<T>(
            object: T,
            ...methodNames: (string|string[])[]
        ): T;
    }


interface LoDashImplicitObjectWrapper<T> {
        /**
         * @see _.bindAll
         */
        bindAll(...methodNames: (string|string[])[]): LoDashImplicitObjectWrapper<T>;
    }


interface LoDashExplicitObjectWrapper<T> {
        /**
         * @see _.bindAll
         */
        bindAll(...methodNames: (string|string[])[]): LoDashExplicitObjectWrapper<T>;
    }


//_.bindKey
interface FunctionBindKey {
        placeholder: any;

        <T extends Object, TResult extends Function>(
            object: T,
            key: any,
            ...partials: any[]
        ): TResult;

        <TResult extends Function>(
            object: Object,
            key: any,
            ...partials: any[]
        ): TResult;
    }


interface LoDashStatic {
        /**
         * Creates a function that invokes the method at object[key] and prepends any additional _.bindKey arguments
         * to those provided to the bound function.
         *
         * This method differs from _.bind by allowing bound functions to reference methods that may be redefined
         * or don’t yet exist. See Peter Michaux’s article for more details.
         *
         * The _.bindKey.placeholder value, which defaults to _ in monolithic builds, may be used as a placeholder
         * for partially applied arguments.
         *
         * @param object The object the method belongs to.
         * @param key The key of the method.
         * @param partials The arguments to be partially applied.
         * @return Returns the new bound function.
         */
        bindKey: FunctionBindKey;
    }


interface LoDashImplicitObjectWrapper<T> {
        /**
         * @see _.bindKey
         */
        bindKey<TResult extends Function>(
            key: any,
            ...partials: any[]
        ): LoDashImplicitObjectWrapper<TResult>;
    }


interface LoDashExplicitObjectWrapper<T> {
        /**
         * @see _.bindKey
         */
        bindKey<TResult extends Function>(
            key: any,
            ...partials: any[]
        ): LoDashExplicitObjectWrapper<TResult>;
    }


//_.createCallback
interface LoDashStatic {
        /**
        * Produces a callback bound to an optional thisArg. If func is a property name the created
        * callback will return the property value for a given element. If func is an object the created
        * callback will return true for elements that contain the equivalent object properties,
        * otherwise it will return false.
        * @param func The value to convert to a callback.
        * @param thisArg The this binding of the created callback.
        * @param argCount The number of arguments the callback accepts.
        * @return A callback function.
        **/
        createCallback(
            func: string,
            thisArg?: any,
            argCount?: number): () => any;

        /**
        * @see _.createCallback
        **/
        createCallback(
            func: Dictionary<any>,
            thisArg?: any,
            argCount?: number): () => boolean;
    }


interface LoDashImplicitWrapper<T> {
        /**
        * @see _.createCallback
        **/
        createCallback(
            thisArg?: any,
            argCount?: number): LoDashImplicitObjectWrapper<() => any>;
    }


interface LoDashImplicitObjectWrapper<T> {
        /**
        * @see _.createCallback
        **/
        createCallback(
            thisArg?: any,
            argCount?: number): LoDashImplicitObjectWrapper<() => any>;
    }


//_.curry
interface LoDashStatic {
        /**
         * Creates a function that accepts one or more arguments of func that when called either invokes func returning
         * its result, if all func arguments have been provided, or returns a function that accepts one or more of the
         * remaining func arguments, and so on. The arity of func may be specified if func.length is not sufficient.
         * @param func The function to curry.
         * @return Returns the new curried function.
         */
        curry<T1, R>(func: (t1: T1) => R):
            CurriedFunction1<T1, R>;
        /**
         * Creates a function that accepts one or more arguments of func that when called either invokes func returning
         * its result, if all func arguments have been provided, or returns a function that accepts one or more of the
         * remaining func arguments, and so on. The arity of func may be specified if func.length is not sufficient.
         * @param func The function to curry.
         * @return Returns the new curried function.
         */
        curry<T1, T2, R>(func: (t1: T1, t2: T2) => R):
            CurriedFunction2<T1, T2, R>;
        /**
         * Creates a function that accepts one or more arguments of func that when called either invokes func returning
         * its result, if all func arguments have been provided, or returns a function that accepts one or more of the
         * remaining func arguments, and so on. The arity of func may be specified if func.length is not sufficient.
         * @param func The function to curry.
         * @return Returns the new curried function.
         */
        curry<T1, T2, T3, R>(func: (t1: T1, t2: T2, t3: T3) => R):
            CurriedFunction3<T1, T2, T3, R>;
        /**
         * Creates a function that accepts one or more arguments of func that when called either invokes func returning
         * its result, if all func arguments have been provided, or returns a function that accepts one or more of the
         * remaining func arguments, and so on. The arity of func may be specified if func.length is not sufficient.
         * @param func The function to curry.
         * @return Returns the new curried function.
         */
        curry<T1, T2, T3, T4, R>(func: (t1: T1, t2: T2, t3: T3, t4: T4) => R):
            CurriedFunction4<T1, T2, T3, T4, R>;
        /**
         * Creates a function that accepts one or more arguments of func that when called either invokes func returning
         * its result, if all func arguments have been provided, or returns a function that accepts one or more of the
         * remaining func arguments, and so on. The arity of func may be specified if func.length is not sufficient.
         * @param func The function to curry.
         * @return Returns the new curried 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>;
        /**
         * Creates a function that accepts one or more arguments of func that when called either invokes func returning
         * its result, if all func arguments have been provided, or returns a function that accepts one or more of the
         * remaining func arguments, and so on. The arity of func may be specified if func.length is not sufficient.
         * @param func The function to curry.
         * @param arity The arity of func.
         * @return Returns the new curried function.
         */
        curry<TResult extends Function>(
          func: Function,
          arity?: number): TResult;
    }


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;
    }


interface LoDashImplicitObjectWrapper<T> {
        /**
        * @see _.curry
        **/
        curry<TResult extends Function>(arity?: number): LoDashImplicitObjectWrapper<TResult>;
    }


//_.curryRight
interface LoDashStatic {
        /**
         * This method is like _.curry except that arguments are applied to func in the manner of _.partialRight
         * instead of _.partial.
         * @param func The function to curry.
         * @return Returns the new curried function.
         */
        curryRight<T1, R>(func: (t1: T1) => R):
            CurriedFunction1<T1, R>;
        /**
         * This method is like _.curry except that arguments are applied to func in the manner of _.partialRight
         * instead of _.partial.
         * @param func The function to curry.
         * @return Returns the new curried function.
         */
        curryRight<T1, T2, R>(func: (t1: T1, t2: T2) => R):
            CurriedFunction2<T2, T1, R>;
        /**
         * This method is like _.curry except that arguments are applied to func in the manner of _.partialRight
         * instead of _.partial.
         * @param func The function to curry.
         * @return Returns the new curried function.
         */
        curryRight<T1, T2, T3, R>(func: (t1: T1, t2: T2, t3: T3) => R):
            CurriedFunction3<T3, T2, T1, R>;
        /**
         * This method is like _.curry except that arguments are applied to func in the manner of _.partialRight
         * instead of _.partial.
         * @param func The function to curry.
         * @return Returns the new curried function.
         */
        curryRight<T1, T2, T3, T4, R>(func: (t1: T1, t2: T2, t3: T3, t4: T4) => R):
            CurriedFunction4<T4, T3, T2, T1, R>;
        /**
         * This method is like _.curry except that arguments are applied to func in the manner of _.partialRight
         * instead of _.partial.
         * @param func The function to curry.
         * @return Returns the new curried function.
         */
        curryRight<T1, T2, T3, T4, T5, R>(func: (t1: T1, t2: T2, t3: T3, t4: T4, t5: T5) => R):
            CurriedFunction5<T5, T4, T3, T2, T1, R>;
        /**
         * This method is like _.curry except that arguments are applied to func in the manner of _.partialRight
         * instead of _.partial.
         * @param func The function to curry.
         * @param arity The arity of func.
         * @return Returns the new curried function.
         */
        curryRight<TResult extends Function>(
          func: Function,
          arity?: number): TResult;
    }


interface LoDashImplicitObjectWrapper<T> {
        /**
         * @see _.curryRight
         **/
        curryRight<TResult extends Function>(arity?: number): LoDashImplicitObjectWrapper<TResult>;
    }


//_.debounce
interface DebounceSettings {
        /**
         * Specify invoking on the leading edge of the timeout.
         */
        leading?: boolean;

        /**
         * The maximum time func is allowed to be delayed before it’s invoked.
         */
        maxWait?: number;

        /**
         * Specify invoking on the trailing edge of the timeout.
         */
        trailing?: boolean;
    }


interface LoDashStatic {
        /**
         * Creates a debounced function that delays invoking func until after wait milliseconds have elapsed since
         * the last time the debounced function was invoked. The debounced function comes with a cancel method to
         * cancel delayed invocations. Provide an options object to indicate that func should be invoked on the
         * leading and/or trailing edge of the wait timeout. Subsequent calls to the debounced function return the
         * result of the last func invocation.
         *
         * Note: If leading and trailing options are true, func is invoked on the trailing edge of the timeout only
         * if the the debounced function is invoked more than once during the wait timeout.
         *
         * See David Corbacho’s article for details over the differences between _.debounce and _.throttle.
         *
         * @param func The function to debounce.
         * @param wait The number of milliseconds to delay.
         * @param options The options object.
         * @param options.leading Specify invoking on the leading edge of the timeout.
         * @param options.maxWait The maximum time func is allowed to be delayed before it’s invoked.
         * @param options.trailing Specify invoking on the trailing edge of the timeout.
         * @return Returns the new debounced function.
         */
        debounce<T extends Function>(
            func: T,
            wait?: number,
            options?: DebounceSettings
        ): T & Cancelable;
    }


interface LoDashImplicitObjectWrapper<T> {
        /**
         * @see _.debounce
         */
        debounce(
            wait?: number,
            options?: DebounceSettings
        ): LoDashImplicitObjectWrapper<T & Cancelable>;
    }


interface LoDashExplicitObjectWrapper<T> {
        /**
         * @see _.debounce
         */
        debounce(
            wait?: number,
            options?: DebounceSettings
        ): LoDashExplicitObjectWrapper<T & Cancelable>;
    }


//_.defer
interface LoDashStatic {
        /**
         * Defers invoking the func until the current call stack has cleared. Any additional arguments are provided to
         * func when it’s invoked.
         *
         * @param func The function to defer.
         * @param args The arguments to invoke the function with.
         * @return Returns the timer id.
         */
        defer<T extends Function>(
            func: T,
            ...args: any[]
        ): number;
    }


interface LoDashImplicitObjectWrapper<T> {
        /**
         * @see _.defer
         */
        defer(...args: any[]): LoDashImplicitWrapper<number>;
    }


interface LoDashExplicitObjectWrapper<T> {
        /**
         * @see _.defer
         */
        defer(...args: any[]): LoDashExplicitWrapper<number>;
    }


//_.delay
interface LoDashStatic {
        /**
         * Invokes func after wait milliseconds. Any additional arguments are provided to func when it’s invoked.
         *
         * @param func The function to delay.
         * @param wait The number of milliseconds to delay invocation.
         * @param args The arguments to invoke the function with.
         * @return Returns the timer id.
         */
        delay<T extends Function>(
            func: T,
            wait: number,
            ...args: any[]
        ): number;
    }


interface LoDashImplicitObjectWrapper<T> {
        /**
         * @see _.delay
         */
        delay(
            wait: number,
            ...args: any[]
        ): LoDashImplicitWrapper<number>;
    }


interface LoDashExplicitObjectWrapper<T> {
        /**
         * @see _.delay
         */
        delay(
            wait: number,
            ...args: any[]
        ): LoDashExplicitWrapper<number>;
    }


interface LoDashStatic {
        /**
         * Creates a function that invokes `func` with arguments reversed.
         *
         * @static
         * @memberOf _
         * @category Function
         * @param {Function} func The function to flip arguments for.
         * @returns {Function} Returns the new function.
         * @example
         *
         * var flipped = _.flip(function() {
         *   return _.toArray(arguments);
         * });
         *
         * flipped('a', 'b', 'c', 'd');
         * // => ['d', 'c', 'b', 'a']
         */
        flip<T extends Function>(func: T): T;
    }


interface LoDashImplicitObjectWrapper<T> {
        /**
         * @see _.flip
         */
        flip(): LoDashImplicitObjectWrapper<T>;
    }


interface LoDashExplicitObjectWrapper<T> {
        /**
         * @see _.flip
         */
        flip(): LoDashExplicitObjectWrapper<T>;
    }


//_.flow
interface LoDashStatic {
        /**
         * Creates a function that returns the result of invoking the provided functions with the this binding of the
         * created function, where each successive invocation is supplied the return value of the previous.
         *
         * @param funcs Functions to invoke.
         * @return Returns the new function.
         */
        flow<TResult extends Function>(...funcs: Function[]): TResult;
    }


interface LoDashImplicitObjectWrapper<T> {
        /**
         * @see _.flow
         */
        flow<TResult extends Function>(...funcs: Function[]): LoDashImplicitObjectWrapper<TResult>;
    }


interface LoDashExplicitObjectWrapper<T> {
        /**
         * @see _.flow
         */
        flow<TResult extends Function>(...funcs: Function[]): LoDashExplicitObjectWrapper<TResult>;
    }


//_.flowRight
interface LoDashStatic {
        /**
         * This method is like _.flow except that it creates a function that invokes the provided functions from right
         * to left.
         *
         * @param funcs Functions to invoke.
         * @return Returns the new function.
         */
        flowRight<TResult extends Function>(...funcs: Function[]): TResult;
    }


interface LoDashImplicitObjectWrapper<T> {
        /**
         * @see _.flowRight
         */
        flowRight<TResult extends Function>(...funcs: Function[]): LoDashImplicitObjectWrapper<TResult>;
    }


interface LoDashExplicitObjectWrapper<T> {
        /**
         * @see _.flowRight
         */
        flowRight<TResult extends Function>(...funcs: Function[]): LoDashExplicitObjectWrapper<TResult>;
    }


//_.memoize
interface MemoizedFunction extends Function {
        cache: MapCache;
    }


interface LoDashStatic {
        /**
         * Creates a function that memoizes the result of func. If resolver is provided it determines the cache key for
         * storing the result based on the arguments provided to the memoized function. By default, the first argument
         * provided to the memoized function is coerced to a string and used as the cache key. The func is invoked with
         * the this binding of the memoized function.
         * @param func The function to have its output memoized.
         * @param resolver The function to resolve the cache key.
         * @return Returns the new memoizing function.
         */
        memoize: {
            <T extends Function>(func: T, resolver?: Function): T & MemoizedFunction;
            Cache: MapCache;
        }
    }


interface LoDashImplicitObjectWrapper<T> {
        /**
         * @see _.memoize
         */
        memoize(resolver?: Function): LoDashImplicitObjectWrapper<T & MemoizedFunction>;
    }


//_.overArgs (was _.modArgs)
interface LoDashStatic {
        /**
         * Creates a function that runs each argument through a corresponding transform function.
         *
         * @param func The function to wrap.
         * @param transforms The functions to transform arguments, specified as individual functions or arrays
         * of functions.
         * @return Returns the new function.
         */
        overArgs<T extends Function, TResult extends Function>(
            func: T,
            ...transforms: Function[]
        ): TResult;

        /**
         * @see _.overArgs
         */
        overArgs<T extends Function, TResult extends Function>(
            func: T,
            transforms: Function[]
        ): TResult;
    }


interface LoDashImplicitObjectWrapper<T> {
        /**
         * @see _.overArgs
         */
        overArgs<TResult extends Function>(...transforms: Function[]): LoDashImplicitObjectWrapper<TResult>;

        /**
         * @see _.overArgs
         */
        overArgs<TResult extends Function>(transforms: Function[]): LoDashImplicitObjectWrapper<TResult>;
    }


interface LoDashExplicitObjectWrapper<T> {
        /**
         * @see _.overArgs
         */
        overArgs<TResult extends Function>(...transforms: Function[]): LoDashExplicitObjectWrapper<TResult>;

        /**
         * @see _.overArgs
         */
        overArgs<TResult extends Function>(transforms: Function[]): LoDashExplicitObjectWrapper<TResult>;
    }


//_.negate
interface LoDashStatic {
        /**
         * Creates a function that negates the result of the predicate func. The func predicate is invoked with
         * the this binding and arguments of the created function.
         *
         * @param predicate The predicate to negate.
         * @return Returns the new function.
         */
        negate<T extends Function>(predicate: T): (...args: any[]) => boolean;

        /**
         * @see _.negate
         */
        negate<T extends Function, TResult extends Function>(predicate: T): TResult;
    }


interface LoDashImplicitObjectWrapper<T> {
        /**
         * @see _.negate
         */
        negate(): LoDashImplicitObjectWrapper<(...args: any[]) => boolean>;

        /**
         * @see _.negate
         */
        negate<TResult extends Function>(): LoDashImplicitObjectWrapper<TResult>;
    }


interface LoDashExplicitObjectWrapper<T> {
        /**
         * @see _.negate
         */
        negate(): LoDashExplicitObjectWrapper<(...args: any[]) => boolean>;

        /**
         * @see _.negate
         */
        negate<TResult extends Function>(): LoDashExplicitObjectWrapper<TResult>;
    }


//_.once
interface LoDashStatic {
        /**
         * Creates a function that is restricted to invoking func once. Repeat calls to the function return the value
         * of the first call. The func is invoked with the this binding and arguments of the created function.
         *
         * @param func The function to restrict.
         * @return Returns the new restricted function.
         */
        once<T extends Function>(func: T): T;
    }


interface LoDashImplicitObjectWrapper<T> {
        /**
         * @see _.once
         */
        once(): LoDashImplicitObjectWrapper<T>;
    }


interface LoDashExplicitObjectWrapper<T> {
        /**
         * @see _.once
         */
        once(): LoDashExplicitObjectWrapper<T>;
    }


//_.partial
interface LoDashStatic {
        /**
        * Creates a function that, when called, invokes func with any additional partial arguments
        * prepended to those provided to the new function. This method is similar to _.bind except
        * it does not alter the this binding.
        * @param func The function to partially apply arguments to.
        * @param args Arguments to be partially applied.
        * @return The new partially applied function.
        **/
        partial: Partial;
    }


interface Function0<R> {
        (): R;
    }


interface Function1<T1, R> {
        (t1: T1): R;
    }


interface Function2<T1, T2, R> {
        (t1: T1, t2: T2): R;
    }


interface Function3<T1, T2, T3, R> {
        (t1: T1, t2: T2, t3: T3): R;
    }


interface Function4<T1, T2, T3, T4, R> {
        (t1: T1, t2: T2, t3: T3, t4: T4): R;
    }


interface Partial {
        // arity 0
        <R>(func: Function0<R>): Function0<R>;
        // arity 1
        <T1, R>(func: Function1<T1, R>): Function1<T1, R>;
        <T1, R>(func: Function1<T1, R>, arg1: T1): Function0<R>;
        // arity 2
        <T1, T2, R>(func: Function2<T1, T2, R>):                      Function2<T1, T2, R>;
        <T1, T2, R>(func: Function2<T1, T2, R>, arg1: T1):            Function1<    T2, R>;
        <T1, T2, R>(func: Function2<T1, T2, R>, plc1: PH, arg2: T2):  Function1<T1,     R>;
        <T1, T2, R>(func: Function2<T1, T2, R>, arg1: T1, arg2: T2):  Function0<        R>;
        // arity 3
        <T1, T2, T3, R>(func: Function3<T1, T2, T3, R>):                                Function3<T1, T2, T3, R>;
        <T1, T2, T3, R>(func: Function3<T1, T2, T3, R>, arg1: T1):                      Function2<    T2, T3, R>;
        <T1, T2, T3, R>(func: Function3<T1, T2, T3, R>, plc1: PH, arg2: T2):            Function2<T1,     T3, R>;
        <T1, T2, T3, R>(func: Function3<T1, T2, T3, R>, arg1: T1, arg2: T2):            Function1<        T3, R>;
        <T1, T2, T3, R>(func: Function3<T1, T2, T3, R>, plc1: PH, plc2: PH, arg3: T3):  Function2<T1, T2,     R>;
        <T1, T2, T3, R>(func: Function3<T1, T2, T3, R>, arg1: T1, plc2: PH, arg3: T3):  Function1<    T2,     R>;
        <T1, T2, T3, R>(func: Function3<T1, T2, T3, R>, plc1: PH, arg2: T2, arg3: T3):  Function1<T1,         R>;
        <T1, T2, T3, R>(func: Function3<T1, T2, T3, R>, arg1: T1, arg2: T2, arg3: T3):  Function0<            R>;
        // arity 4
        <T1, T2, T3, T4, R>(func: Function4<T1, T2, T3, T4, R>):                                          Function4<T1, T2, T3, T4, R>;
        <T1, T2, T3, T4, R>(func: Function4<T1, T2, T3, T4, R>, arg1: T1):                                Function3<    T2, T3, T4, R>;
        <T1, T2, T3, T4, R>(func: Function4<T1, T2, T3, T4, R>, plc1: PH, arg2: T2):                      Function3<T1,     T3, T4, R>;
        <T1, T2, T3, T4, R>(func: Function4<T1, T2, T3, T4, R>, arg1: T1, arg2: T2):                      Function2<        T3, T4, R>;
        <T1, T2, T3, T4, R>(func: Function4<T1, T2, T3, T4, R>, plc1: PH, plc2: PH, arg3: T3):            Function3<T1, T2,     T4, R>;
        <T1, T2, T3, T4, R>(func: Function4<T1, T2, T3, T4, R>, arg1: T1, plc2: PH, arg3: T3):            Function2<    T2,     T4, R>;
        <T1, T2, T3, T4, R>(func: Function4<T1, T2, T3, T4, R>, plc1: PH, arg2: T2, arg3: T3):            Function2<T1,         T4, R>;
        <T1, T2, T3, T4, R>(func: Function4<T1, T2, T3, T4, R>, arg1: T1, arg2: T2, arg3: T3):            Function1<            T4, R>;
        <T1, T2, T3, T4, R>(func: Function4<T1, T2, T3, T4, R>, plc1: PH, plc2: PH, plc3: PH, arg4: T4):  Function3<T1, T2, T3,     R>;
        <T1, T2, T3, T4, R>(func: Function4<T1, T2, T3, T4, R>, arg1: T1, plc2: PH, plc3: PH, arg4: T4):  Function2<    T2, T3,     R>;
        <T1, T2, T3, T4, R>(func: Function4<T1, T2, T3, T4, R>, plc1: PH, arg2: T2, plc3: PH, arg4: T4):  Function2<T1,     T3,     R>;
        <T1, T2, T3, T4, R>(func: Function4<T1, T2, T3, T4, R>, arg1: T1, arg2: T2, plc3: PH, arg4: T4):  Function1<        T3,     R>;
        <T1, T2, T3, T4, R>(func: Function4<T1, T2, T3, T4, R>, plc1: PH, plc2: PH, arg3: T3, arg4: T4):  Function2<T1, T2,         R>;
        <T1, T2, T3, T4, R>(func: Function4<T1, T2, T3, T4, R>, arg1: T1, plc2: PH, arg3: T3, arg4: T4):  Function1<    T2,         R>;
        <T1, T2, T3, T4, R>(func: Function4<T1, T2, T3, T4, R>, plc1: PH, arg2: T2, arg3: T3, arg4: T4):  Function1<T1,             R>;
        <T1, T2, T3, T4, R>(func: Function4<T1, T2, T3, T4, R>, arg1: T1, arg2: T2, arg3: T3, arg4: T4):  Function0<                R>;
        // catch-all
        (func: Function, ...args: any[]): Function;
    }


//_.partialRight
interface LoDashStatic {
        /**
        * This method is like _.partial except that partial arguments are appended to those provided
        * to the new function.
        * @param func The function to partially apply arguments to.
        * @param args Arguments to be partially applied.
        * @return The new partially applied function.
        **/
        partialRight: PartialRight
    }


interface PartialRight {
        // arity 0
        <R>(func: Function0<R>): Function0<R>;
        // arity 1
        <T1, R>(func: Function1<T1, R>): Function1<T1, R>;
        <T1, R>(func: Function1<T1, R>, arg1: T1): Function0<R>;
        // arity 2
        <T1, T2, R>(func: Function2<T1, T2, R>):                      Function2<T1, T2, R>;
        <T1, T2, R>(func: Function2<T1, T2, R>, arg1: T1, plc2: PH):  Function1<    T2, R>;
        <T1, T2, R>(func: Function2<T1, T2, R>,           arg2: T2):  Function1<T1,     R>;
        <T1, T2, R>(func: Function2<T1, T2, R>, arg1: T1, arg2: T2):  Function0<        R>;
        // arity 3
        <T1, T2, T3, R>(func: Function3<T1, T2, T3, R>):                                Function3<T1, T2, T3, R>;
        <T1, T2, T3, R>(func: Function3<T1, T2, T3, R>, arg1: T1, plc2: PH, plc3: PH):  Function2<    T2, T3, R>;
        <T1, T2, T3, R>(func: Function3<T1, T2, T3, R>,           arg2: T2, plc3: PH):  Function2<T1,     T3, R>;
        <T1, T2, T3, R>(func: Function3<T1, T2, T3, R>, arg1: T1, arg2: T2, plc3: PH):  Function1<        T3, R>;
        <T1, T2, T3, R>(func: Function3<T1, T2, T3, R>,                     arg3: T3):  Function2<T1, T2,     R>;
        <T1, T2, T3, R>(func: Function3<T1, T2, T3, R>, arg1: T1, plc2: PH, arg3: T3):  Function1<    T2,     R>;
        <T1, T2, T3, R>(func: Function3<T1, T2, T3, R>,           arg2: T2, arg3: T3):  Function1<T1,         R>;
        <T1, T2, T3, R>(func: Function3<T1, T2, T3, R>, arg1: T1, arg2: T2, arg3: T3):  Function0<            R>;
        // arity 4
        <T1, T2, T3, T4, R>(func: Function4<T1, T2, T3, T4, R>):                                          Function4<T1, T2, T3, T4, R>;
        <T1, T2, T3, T4, R>(func: Function4<T1, T2, T3, T4, R>, arg1: T1, plc2: PH, plc3: PH, plc4: PH):  Function3<    T2, T3, T4, R>;
        <T1, T2, T3, T4, R>(func: Function4<T1, T2, T3, T4, R>,           arg2: T2, plc3: PH, plc4: PH):  Function3<T1,     T3, T4, R>;
        <T1, T2, T3, T4, R>(func: Function4<T1, T2, T3, T4, R>, arg1: T1, arg2: T2, plc3: PH, plc4: PH):  Function2<        T3, T4, R>;
        <T1, T2, T3, T4, R>(func: Function4<T1, T2, T3, T4, R>,                     arg3: T3, plc4: PH):  Function3<T1, T2,     T4, R>;
        <T1, T2, T3, T4, R>(func: Function4<T1, T2, T3, T4, R>, arg1: T1, plc2: PH, arg3: T3, plc4: PH):  Function2<    T2,     T4, R>;
        <T1, T2, T3, T4, R>(func: Function4<T1, T2, T3, T4, R>,           arg2: T2, arg3: T3, plc4: PH):  Function2<T1,         T4, R>;
        <T1, T2, T3, T4, R>(func: Function4<T1, T2, T3, T4, R>, arg1: T1, arg2: T2, arg3: T3, plc4: PH):  Function1<            T4, R>;
        <T1, T2, T3, T4, R>(func: Function4<T1, T2, T3, T4, R>,                               arg4: T4):  Function3<T1, T2, T3,     R>;
        <T1, T2, T3, T4, R>(func: Function4<T1, T2, T3, T4, R>, arg1: T1, plc2: PH, plc3: PH, arg4: T4):  Function2<    T2, T3,     R>;
        <T1, T2, T3, T4, R>(func: Function4<T1, T2, T3, T4, R>,           arg2: T2, plc3: PH, arg4: T4):  Function2<T1,     T3,     R>;
        <T1, T2, T3, T4, R>(func: Function4<T1, T2, T3, T4, R>, arg1: T1, arg2: T2, plc3: PH, arg4: T4):  Function1<        T3,     R>;
        <T1, T2, T3, T4, R>(func: Function4<T1, T2, T3, T4, R>,                     arg3: T3, arg4: T4):  Function2<T1, T2,         R>;
        <T1, T2, T3, T4, R>(func: Function4<T1, T2, T3, T4, R>, arg1: T1, plc2: PH, arg3: T3, arg4: T4):  Function1<    T2,         R>;
        <T1, T2, T3, T4, R>(func: Function4<T1, T2, T3, T4, R>,           arg2: T2, arg3: T3, arg4: T4):  Function1<T1,             R>;
        <T1, T2, T3, T4, R>(func: Function4<T1, T2, T3, T4, R>, arg1: T1, arg2: T2, arg3: T3, arg4: T4):  Function0<                R>;
        // catch-all
        (func: Function, ...args: any[]): Function;
    }


//_.rearg
interface LoDashStatic {
        /**
         * Creates a function that invokes func with arguments arranged according to the specified indexes where the
         * argument value at the first index is provided as the first argument, the argument value at the second index
         * is provided as the second argument, and so on.
         * @param func The function to rearrange arguments for.
         * @param indexes The arranged argument indexes, specified as individual indexes or arrays of indexes.
         * @return Returns the new function.
         */
        rearg<TResult extends Function>(func: Function, indexes: number[]): TResult;

        /**
         * @see _.rearg
         */
        rearg<TResult extends Function>(func: Function, ...indexes: number[]): TResult;
    }


interface LoDashImplicitObjectWrapper<T> {
        /**
         * @see _.rearg
         */
        rearg<TResult extends Function>(indexes: number[]): LoDashImplicitObjectWrapper<TResult>;

        /**
         * @see _.rearg
         */
        rearg<TResult extends Function>(...indexes: number[]): LoDashImplicitObjectWrapper<TResult>;
    }


//_.rest
interface LoDashStatic {
        /**
         * Creates a function that invokes func with the this binding of the created function and arguments from start
         * and beyond provided as an array.
         *
         * Note: This method is based on the rest parameter.
         *
         * @param func The function to apply a rest parameter to.
         * @param start The start position of the rest parameter.
         * @return Returns the new function.
         */
        rest<TResult extends Function>(
            func: Function,
            start?: number
        ): TResult;

        /**
         * @see _.rest
         */
        rest<TResult extends Function, TFunc extends Function>(
            func: TFunc,
            start?: number
        ): TResult;
    }


interface LoDashImplicitObjectWrapper<T> {
        /**
         * @see _.rest
         */
        rest<TResult extends Function>(start?: number): LoDashImplicitObjectWrapper<TResult>;
    }


interface LoDashExplicitObjectWrapper<T> {
        /**
         * @see _.rest
         */
        rest<TResult extends Function>(start?: number): LoDashExplicitObjectWrapper<TResult>;
    }