//_.spread
interface LoDashStatic {
        /**
         * Creates a function that invokes func with the this binding of the created function and an array of arguments
         * much like Function#apply.
         *
         * Note: This method is based on the spread operator.
         *
         * @param func The function to spread arguments over.
         * @return Returns the new function.
         */
        spread<F extends Function, T extends Function>(func: F): T;

        /**
         * @see _.spread
         */
        spread<T extends Function>(func: Function): T;
    }


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


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


//_.throttle
interface ThrottleSettings {
        /**
         * If you'd like to disable the leading-edge call, pass this as false.
         */
        leading?: boolean;

        /**
         * If you'd like to disable the execution on the trailing-edge, pass false.
         */
        trailing?: boolean;
    }


interface LoDashStatic {
        /**
         * Creates a throttled function that only invokes func at most once per every wait milliseconds. The throttled
         * 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 throttled function return the result of the last func call.
         *
         * Note: If leading and trailing options are true, func is invoked on the trailing edge of the timeout only if
         * the the throttled function is invoked more than once during the wait timeout.
         *
         * @param func The function to throttle.
         * @param wait The number of milliseconds to throttle invocations to.
         * @param options The options object.
         * @param options.leading Specify invoking on the leading edge of the timeout.
         * @param options.trailing Specify invoking on the trailing edge of the timeout.
         * @return Returns the new throttled function.
         */
        throttle<T extends Function>(
            func: T,
            wait?: number,
            options?: ThrottleSettings
        ): T & Cancelable;
    }


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


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


//_.unary
interface LoDashStatic {
        /**
         * Creates a function that accepts up to one argument, ignoring any
         * additional arguments.
         *
         * @static
         * @memberOf _
         * @category Function
         * @param {Function} func The function to cap arguments for.
         * @returns {Function} Returns the new function.
         * @example
         *
         * _.map(['6', '8', '10'], _.unary(parseInt));
         * // => [6, 8, 10]
         */
        unary<T extends Function>(func: T): T;
    }


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


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


//_.wrap
interface LoDashStatic {
        /**
         * Creates a function that provides value to the wrapper function as its first argument. Any additional
         * arguments provided to the function are appended to those provided to the wrapper function. The wrapper is
         * invoked with the this binding of the created function.
         *
         * @param value The value to wrap.
         * @param wrapper The wrapper function.
         * @return Returns the new function.
         */
        wrap<V, W extends Function, R extends Function>(
            value: V,
            wrapper: W
        ): R;

        /**
         * @see _.wrap
         */
        wrap<V, R extends Function>(
            value: V,
            wrapper: Function
        ): R;

        /**
         * @see _.wrap
         */
        wrap<R extends Function>(
            value: any,
            wrapper: Function
        ): R;
    }


interface LoDashImplicitWrapper<T> {
        /**
         * @see _.wrap
         */
        wrap<W extends Function, R extends Function>(wrapper: W): LoDashImplicitObjectWrapper<R>;

        /**
         * @see _.wrap
         */
        wrap<R extends Function>(wrapper: Function): LoDashImplicitObjectWrapper<R>;
    }


interface LoDashImplicitArrayWrapper<T> {
        /**
         * @see _.wrap
         */
        wrap<W extends Function, R extends Function>(wrapper: W): LoDashImplicitObjectWrapper<R>;

        /**
         * @see _.wrap
         */
        wrap<R extends Function>(wrapper: Function): LoDashImplicitObjectWrapper<R>;
    }


interface LoDashImplicitObjectWrapper<T> {
        /**
         * @see _.wrap
         */
        wrap<W extends Function, R extends Function>(wrapper: W): LoDashImplicitObjectWrapper<R>;

        /**
         * @see _.wrap
         */
        wrap<R extends Function>(wrapper: Function): LoDashImplicitObjectWrapper<R>;
    }


interface LoDashExplicitWrapper<T> {
        /**
         * @see _.wrap
         */
        wrap<W extends Function, R extends Function>(wrapper: W): LoDashExplicitObjectWrapper<R>;

        /**
         * @see _.wrap
         */
        wrap<R extends Function>(wrapper: Function): LoDashExplicitObjectWrapper<R>;
    }


interface LoDashExplicitArrayWrapper<T> {
        /**
         * @see _.wrap
         */
        wrap<W extends Function, R extends Function>(wrapper: W): LoDashExplicitObjectWrapper<R>;

        /**
         * @see _.wrap
         */
        wrap<R extends Function>(wrapper: Function): LoDashExplicitObjectWrapper<R>;
    }


interface LoDashExplicitObjectWrapper<T> {
        /**
         * @see _.wrap
         */
        wrap<W extends Function, R extends Function>(wrapper: W): LoDashExplicitObjectWrapper<R>;

        /**
         * @see _.wrap
         */
        wrap<R extends Function>(wrapper: Function): LoDashExplicitObjectWrapper<R>;
    }


/********
     * Lang *
     ********/
//_.castArray
interface LoDashStatic {
        /**
         * Casts value as an array if it’s not one.
         *
         * @param value The value to inspect.
         * @return Returns the cast array.
         */
        castArray<T>(value: T): T[];
    }


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


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


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


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


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


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


//_.clone
interface LoDashStatic {
        /**
         * Creates a shallow clone of value.
         *
         * Note: This method is loosely based on the structured clone algorithm and supports cloning arrays,
         * array buffers, booleans, date objects, maps, numbers, Object objects, regexes, sets, strings, symbols,
         * and typed arrays. The own enumerable properties of arguments objects are cloned as plain objects. An empty
         * object is returned for uncloneable values such as error objects, functions, DOM nodes, and WeakMaps.
         *
         * @param value The value to clone.
         * @return Returns the cloned value.
         */
        clone<T>(value: T): T;
    }


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


interface LoDashImplicitArrayWrapper<T> {

        /**
         * @see _.clone
         */
        clone(): T[];
    }


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


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


interface LoDashExplicitArrayWrapper<T> {

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


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


//_.cloneDeep
interface LoDashStatic {
        /**
         * This method is like _.clone except that it recursively clones value.
         *
         * @param value The value to recursively clone.
         * @return Returns the deep cloned value.
         */
        cloneDeep<T>(value: T): T;
    }


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


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


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


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


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


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


//_.cloneDeepWith
interface CloneDeepWithCustomizer<TValue, TResult> {
        (value: TValue): TResult;
    }


interface LoDashStatic {
        /**
         * This method is like _.cloneWith except that it recursively clones value.
         *
         * @param value The value to recursively clone.
         * @param customizer The function to customize cloning.
         * @return Returns the deep cloned value.
         */
        cloneDeepWith<TResult>(
            value: any,
            customizer?: CloneDeepWithCustomizer<any, TResult>
        ): TResult;

        /**
         * @see _.clonDeepeWith
         */
        cloneDeepWith<T, TResult>(
            value: T,
            customizer?: CloneDeepWithCustomizer<T, TResult>
        ): TResult;
    }


interface LoDashImplicitWrapper<T> {
        /**
         * @see _.cloneDeepWith
         */
        cloneDeepWith<TResult>(
            customizer?: CloneDeepWithCustomizer<T, TResult>
        ): TResult;
    }


interface LoDashImplicitArrayWrapper<T> {
        /**
         * @see _.cloneDeepWith
         */
        cloneDeepWith<TResult>(
            customizer?: CloneDeepWithCustomizer<T[], TResult>
        ): TResult;
    }


interface LoDashImplicitObjectWrapper<T> {
        /**
         * @see _.cloneDeepWith
         */
        cloneDeepWith<TResult>(
            customizer?: CloneDeepWithCustomizer<T, TResult>
        ): TResult;
    }


interface LoDashExplicitWrapper<T> {
        /**
         * @see _.cloneDeepWith
         */
        cloneDeepWith<TResult extends (number|string|boolean)>(
            customizer?: CloneDeepWithCustomizer<T, TResult>
        ): LoDashExplicitWrapper<TResult>;

        /**
         * @see _.cloneDeepWith
         */
        cloneDeepWith<TResult>(
            customizer?: CloneDeepWithCustomizer<T, TResult[]>
        ): LoDashExplicitArrayWrapper<TResult>;

        /**
         * @see _.cloneDeepWith
         */
        cloneDeepWith<TResult extends Object>(
            customizer?: CloneDeepWithCustomizer<T, TResult>
        ): LoDashExplicitObjectWrapper<TResult>;
    }


interface LoDashExplicitArrayWrapper<T> {
        /**
         * @see _.cloneDeepWith
         */
        cloneDeepWith<TResult extends (number|string|boolean)>(
            customizer?: CloneDeepWithCustomizer<T[], TResult>
        ): LoDashExplicitWrapper<TResult>;

        /**
         * @see _.cloneDeepWith
         */
        cloneDeepWith<TResult>(
            customizer?: CloneDeepWithCustomizer<T[], TResult[]>
        ): LoDashExplicitArrayWrapper<TResult>;

        /**
         * @see _.cloneDeepWith
         */
        cloneDeepWith<TResult extends Object>(
            customizer?: CloneDeepWithCustomizer<T[], TResult>
        ): LoDashExplicitObjectWrapper<TResult>;
    }


interface LoDashExplicitObjectWrapper<T> {
        /**
         * @see _.cloneDeepWith
         */
        cloneDeepWith<TResult extends (number|string|boolean)>(
            customizer?: CloneDeepWithCustomizer<T, TResult>
        ): LoDashExplicitWrapper<TResult>;

        /**
         * @see _.cloneDeepWith
         */
        cloneDeepWith<TResult>(
            customizer?: CloneDeepWithCustomizer<T, TResult[]>
        ): LoDashExplicitArrayWrapper<TResult>;

        /**
         * @see _.cloneDeepWith
         */
        cloneDeepWith<TResult extends Object>(
            customizer?: CloneDeepWithCustomizer<T, TResult>
        ): LoDashExplicitObjectWrapper<TResult>;
    }


//_.cloneWith
interface CloneWithCustomizer<TValue, TResult> {
        (value: TValue): TResult;
    }


interface LoDashStatic {
        /**
         * This method is like _.clone except that it accepts customizer which is invoked to produce the cloned value.
         * If customizer returns undefined cloning is handled by the method instead.
         *
         * @param value The value to clone.
         * @param customizer The function to customize cloning.
         * @return Returns the cloned value.
         */
        cloneWith<TResult>(
            value: any,
            customizer?: CloneWithCustomizer<any, TResult>
        ): TResult;

        /**
         * @see _.cloneWith
         */
        cloneWith<T, TResult>(
            value: T,
            customizer?: CloneWithCustomizer<T, TResult>
        ): TResult;
    }


interface LoDashImplicitWrapper<T> {
        /**
         * @see _.cloneWith
         */
        cloneWith<TResult>(
            customizer?: CloneWithCustomizer<T, TResult>
        ): TResult;
    }


interface LoDashImplicitArrayWrapper<T> {
        /**
         * @see _.cloneWith
         */
        cloneWith<TResult>(
            customizer?: CloneWithCustomizer<T[], TResult>
        ): TResult;
    }


interface LoDashImplicitObjectWrapper<T> {
        /**
         * @see _.cloneWith
         */
        cloneWith<TResult>(
            customizer?: CloneWithCustomizer<T, TResult>
        ): TResult;
    }


interface LoDashExplicitWrapper<T> {
        /**
         * @see _.cloneWith
         */
        cloneWith<TResult extends (number|string|boolean)>(
            customizer?: CloneWithCustomizer<T, TResult>
        ): LoDashExplicitWrapper<TResult>;

        /**
         * @see _.cloneWith
         */
        cloneWith<TResult>(
            customizer?: CloneWithCustomizer<T, TResult[]>
        ): LoDashExplicitArrayWrapper<TResult>;

        /**
         * @see _.cloneWith
         */
        cloneWith<TResult extends Object>(
            customizer?: CloneWithCustomizer<T, TResult>
        ): LoDashExplicitObjectWrapper<TResult>;
    }


interface LoDashExplicitArrayWrapper<T> {
        /**
         * @see _.cloneWith
         */
        cloneWith<TResult extends (number|string|boolean)>(
            customizer?: CloneWithCustomizer<T[], TResult>
        ): LoDashExplicitWrapper<TResult>;

        /**
         * @see _.cloneWith
         */
        cloneWith<TResult>(
            customizer?: CloneWithCustomizer<T[], TResult[]>
        ): LoDashExplicitArrayWrapper<TResult>;

        /**
         * @see _.cloneWith
         */
        cloneWith<TResult extends Object>(
            customizer?: CloneWithCustomizer<T[], TResult>
        ): LoDashExplicitObjectWrapper<TResult>;
    }


interface LoDashExplicitObjectWrapper<T> {
        /**
         * @see _.cloneWith
         */
        cloneWith<TResult extends (number|string|boolean)>(
            customizer?: CloneWithCustomizer<T, TResult>
        ): LoDashExplicitWrapper<TResult>;

        /**
         * @see _.cloneWith
         */
        cloneWith<TResult>(
            customizer?: CloneWithCustomizer<T, TResult[]>
        ): LoDashExplicitArrayWrapper<TResult>;

        /**
         * @see _.cloneWith
         */
        cloneWith<TResult extends Object>(
            customizer?: CloneWithCustomizer<T, TResult>
        ): LoDashExplicitObjectWrapper<TResult>;
    }


//_.eq
interface LoDashStatic {
        /**
         * Performs a [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
         * comparison between two values to determine if they are equivalent.
         *
         * @static
         * @memberOf _
         * @category Lang
         * @param {*} value The value to compare.
         * @param {*} other The other value to compare.
         * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
         * @example
         *
         * var object = { 'user': 'fred' };
         * var other = { 'user': 'fred' };
         *
         * _.eq(object, object);
         * // => true
         *
         * _.eq(object, other);
         * // => false
         *
         * _.eq('a', 'a');
         * // => true
         *
         * _.eq('a', Object('a'));
         * // => false
         *
         * _.eq(NaN, NaN);
         * // => true
         */
        eq(
            value: any,
            other: any
        ): boolean;
    }


interface LoDashImplicitWrapperBase<T, TWrapper> {
        /**
         * @see _.isEqual
         */
        eq(
            other: any
        ): boolean;
    }


interface LoDashExplicitWrapperBase<T, TWrapper> {
        /**
         * @see _.isEqual
         */
        eq(
            other: any
        ): LoDashExplicitWrapper<boolean>;
    }


//_.gt
interface LoDashStatic {
        /**
         * Checks if value is greater than other.
         *
         * @param value The value to compare.
         * @param other The other value to compare.
         * @return Returns true if value is greater than other, else false.
         */
        gt(
            value: any,
            other: any
        ): boolean;
    }


interface LoDashImplicitWrapperBase<T, TWrapper> {
        /**
         * @see _.gt
         */
        gt(other: any): boolean;
    }


interface LoDashExplicitWrapperBase<T, TWrapper> {
        /**
         * @see _.gt
         */
        gt(other: any): LoDashExplicitWrapper<boolean>;
    }


//_.gte
interface LoDashStatic {
        /**
         * Checks if value is greater than or equal to other.
         *
         * @param value The value to compare.
         * @param other The other value to compare.
         * @return Returns true if value is greater than or equal to other, else false.
         */
        gte(
            value: any,
            other: any
        ): boolean;
    }


interface LoDashImplicitWrapperBase<T, TWrapper> {
        /**
         * @see _.gte
         */
        gte(other: any): boolean;
    }


interface LoDashExplicitWrapperBase<T, TWrapper> {
        /**
         * @see _.gte
         */
        gte(other: any): LoDashExplicitWrapper<boolean>;
    }


//_.isArguments
interface LoDashStatic {
        /**
         * Checks if value is classified as an arguments object.
         *
         * @param value The value to check.
         * @return Returns true if value is correctly classified, else false.
         */
        isArguments(value?: any): value is IArguments;
    }


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


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


//_.isArray
interface LoDashStatic {
        /**
         * Checks if value is classified as an Array object.
         * @param value The value to check.
         *
         * @return Returns true if value is correctly classified, else false.
         */
        isArray<T>(value?: any): value is T[];
    }


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


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


//_.isArrayBuffer
interface LoDashStatic {
        /**
         * Checks if value is classified as an ArrayBuffer object.
         *
         * @param value The value to check.
         * @return Returns true if value is correctly classified, else false.
         */
        isArrayBuffer(value?: any): value is ArrayBuffer;
    }


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


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


//_.isArrayLike
interface LoDashStatic {
        /**
         * Checks if `value` is array-like. A value is considered array-like if it's
         * not a function and has a `value.length` that's an integer greater than or
         * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`.
         *
         * @static
         * @memberOf _
         * @type Function
         * @category Lang
         * @param {*} value The value to check.
         * @returns {boolean} Returns `true` if `value` is array-like, else `false`.
         * @example
         *
         * _.isArrayLike([1, 2, 3]);
         * // => true
         *
         * _.isArrayLike(document.body.children);
         * // => true
         *
         * _.isArrayLike('abc');
         * // => true
         *
         * _.isArrayLike(_.noop);
         * // => false
         */
        isArrayLike<T>(value?: any): value is T[];
    }


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


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


//_.isArrayLikeObject
interface LoDashStatic {
        /**
         * This method is like `_.isArrayLike` except that it also checks if `value`
         * is an object.
         *
         * @static
         * @memberOf _
         * @type Function
         * @category Lang
         * @param {*} value The value to check.
         * @returns {boolean} Returns `true` if `value` is an array-like object, else `false`.
         * @example
         *
         * _.isArrayLikeObject([1, 2, 3]);
         * // => true
         *
         * _.isArrayLikeObject(document.body.children);
         * // => true
         *
         * _.isArrayLikeObject('abc');
         * // => false
         *
         * _.isArrayLikeObject(_.noop);
         * // => false
         */
        isArrayLikeObject<T>(value?: any): value is T[];
    }


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


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


//_.isBoolean
interface LoDashStatic {
        /**
         * Checks if value is classified as a boolean primitive or object.
         *
         * @param value The value to check.
         * @return Returns true if value is correctly classified, else false.
         */
        isBoolean(value?: any): value is boolean;
    }


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


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


//_.isBuffer
interface LoDashStatic {
        /**
         * Checks if value is a buffer.
         *
         * @param value The value to check.
         * @return Returns true if value is a buffer, else false.
         */
        isBuffer(value?: any): boolean;
    }


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


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


//_.isDate
interface LoDashStatic {
        /**
         * Checks if value is classified as a Date object.
         * @param value The value to check.
         *
         * @return Returns true if value is correctly classified, else false.
         */
        isDate(value?: any): value is Date;
    }


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


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


//_.isElement
interface LoDashStatic {
        /**
         * Checks if value is a DOM element.
         *
         * @param value The value to check.
         * @return Returns true if value is a DOM element, else false.
         */
        isElement(value?: any): boolean;
    }


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


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


//_.isEmpty
interface LoDashStatic {
        /**
         * Checks if value is empty. A value is considered empty unless it’s an arguments object, array, string, or
         * jQuery-like collection with a length greater than 0 or an object with own enumerable properties.
         *
         * @param value The value to inspect.
         * @return Returns true if value is empty, else false.
         */
        isEmpty(value?: any): boolean;
    }


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


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


//_.isEqual
interface LoDashStatic {
        /**
         * Performs a deep comparison between two values to determine if they are
         * equivalent.
         *
         * **Note:** This method supports comparing arrays, array buffers, booleans,
         * date objects, error objects, maps, numbers, `Object` objects, regexes,
         * sets, strings, symbols, and typed arrays. `Object` objects are compared
         * by their own, not inherited, enumerable properties. Functions and DOM
         * nodes are **not** supported.
         *
         * @static
         * @memberOf _
         * @category Lang
         * @param {*} value The value to compare.
         * @param {*} other The other value to compare.
         * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
         * @example
         *
         * var object = { 'user': 'fred' };
         * var other = { 'user': 'fred' };
         *
         * _.isEqual(object, other);
         * // => true
         *
         * object === other;
         * // => false
         */
        isEqual(
            value: any,
            other: any
        ): boolean;
    }


interface LoDashImplicitWrapperBase<T, TWrapper> {
        /**
         * @see _.isEqual
         */
        isEqual(
            other: any
        ): boolean;
    }


interface LoDashExplicitWrapperBase<T, TWrapper> {
        /**
         * @see _.isEqual
         */
        isEqual(
            other: any
        ): LoDashExplicitWrapper<boolean>;
    }


// _.isEqualWith
interface IsEqualCustomizer {
        (value: any, other: any, indexOrKey?: number|string): boolean;
    }


interface LoDashStatic {
        /**
         * This method is like `_.isEqual` except that it accepts `customizer` which is
         * invoked to compare values. If `customizer` returns `undefined` comparisons are
         * handled by the method instead. The `customizer` is invoked with up to seven arguments:
         * (objValue, othValue [, index|key, object, other, stack]).
         *
         * @static
         * @memberOf _
         * @category Lang
         * @param {*} value The value to compare.
         * @param {*} other The other value to compare.
         * @param {Function} [customizer] The function to customize comparisons.
         * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
         * @example
         *
         * function isGreeting(value) {
         *   return /^h(?:i|ello)$/.test(value);
         * }
         *
         * function customizer(objValue, othValue) {
         *   if (isGreeting(objValue) && isGreeting(othValue)) {
         *     return true;
         *   }
         * }
         *
         * var array = ['hello', 'goodbye'];
         * var other = ['hi', 'goodbye'];
         *
         * _.isEqualWith(array, other, customizer);
         * // => true
         */
        isEqualWith(
            value: any,
            other: any,
            customizer: IsEqualCustomizer
        ): boolean;
    }


interface LoDashImplicitWrapperBase<T, TWrapper> {
        /**
         * @see _.isEqualWith
         */
        isEqualWith(
            other: any,
            customizer: IsEqualCustomizer
        ): boolean;
    }


interface LoDashExplicitWrapperBase<T, TWrapper> {
        /**
         * @see _.isEqualWith
         */
        isEqualWith(
            other: any,
            customizer: IsEqualCustomizer
        ): LoDashExplicitWrapper<boolean>;
    }


//_.isError
interface LoDashStatic {
        /**
         * Checks if value is an Error, EvalError, RangeError, ReferenceError, SyntaxError, TypeError, or URIError
         * object.
         *
         * @param value The value to check.
         * @return Returns true if value is an error object, else false.
         */
        isError(value: any): value is Error;
    }


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


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


//_.isFinite
interface LoDashStatic {
        /**
         * Checks if value is a finite primitive number.
         *
         * Note: This method is based on Number.isFinite.
         *
         * @param value The value to check.
         * @return Returns true if value is a finite number, else false.
         */
        isFinite(value?: any): boolean;
    }


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


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


//_.isFunction
interface LoDashStatic {
        /**
         * Checks if value is classified as a Function object.
         *
         * @param value The value to check.
         * @return Returns true if value is correctly classified, else false.
         */
        isFunction(value?: any): value is Function;
    }


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


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


//_.isInteger
interface LoDashStatic {
        /**
         * Checks if `value` is an integer.
         *
         * **Note:** This method is based on [`Number.isInteger`](https://mdn.io/Number/isInteger).
         *
         * @static
         * @memberOf _
         * @category Lang
         * @param {*} value The value to check.
         * @returns {boolean} Returns `true` if `value` is an integer, else `false`.
         * @example
         *
         * _.isInteger(3);
         * // => true
         *
         * _.isInteger(Number.MIN_VALUE);
         * // => false
         *
         * _.isInteger(Infinity);
         * // => false
         *
         * _.isInteger('3');
         * // => false
         */
        isInteger(value?: any): boolean;
    }


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


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


//_.isLength
interface LoDashStatic {
        /**
         * Checks if `value` is a valid array-like length.
         *
         * **Note:** This function is loosely based on [`ToLength`](http://ecma-international.org/ecma-262/6.0/#sec-tolength).
         *
         * @static
         * @memberOf _
         * @category Lang
         * @param {*} value The value to check.
         * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.
         * @example
         *
         * _.isLength(3);
         * // => true
         *
         * _.isLength(Number.MIN_VALUE);
         * // => false
         *
         * _.isLength(Infinity);
         * // => false
         *
         * _.isLength('3');
         * // => false
         */
        isLength(value?: any): boolean;
    }


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


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


//_.isMap
interface LoDashStatic {
        /**
         * Checks if value is classified as a Map object.
         *
         * @param value The value to check.
         * @returns Returns true if value is correctly classified, else false.
         */
        isMap<K, V>(value?: any): value is Map<K, V>;
    }


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


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


//_.isMatch
interface isMatchCustomizer {
        (value: any, other: any, indexOrKey?: number|string): boolean;
    }


interface LoDashStatic {
        /**
         * Performs a deep comparison between `object` and `source` to determine if
         * `object` contains equivalent property values.
         *
         * **Note:** This method supports comparing the same values as `_.isEqual`.
         *
         * @static
         * @memberOf _
         * @category Lang
         * @param {Object} object The object to inspect.
         * @param {Object} source The object of property values to match.
         * @returns {boolean} Returns `true` if `object` is a match, else `false`.
         * @example
         *
         * var object = { 'user': 'fred', 'age': 40 };
         *
         * _.isMatch(object, { 'age': 40 });
         * // => true
         *
         * _.isMatch(object, { 'age': 36 });
         * // => false
         */
        isMatch(object: Object, source: Object): boolean;
    }


interface LoDashImplicitObjectWrapper<T> {
        /**
         * @see _.isMatch
         */
        isMatch(source: Object): boolean;
    }


//_.isMatchWith
interface isMatchWithCustomizer {
        (value: any, other: any, indexOrKey?: number|string): boolean;
    }


interface LoDashStatic {
        /**
         * This method is like `_.isMatch` except that it accepts `customizer` which
         * is invoked to compare values. If `customizer` returns `undefined` comparisons
         * are handled by the method instead. The `customizer` is invoked with three
         * arguments: (objValue, srcValue, index|key, object, source).
         *
         * @static
         * @memberOf _
         * @category Lang
         * @param {Object} object The object to inspect.
         * @param {Object} source The object of property values to match.
         * @param {Function} [customizer] The function to customize comparisons.
         * @returns {boolean} Returns `true` if `object` is a match, else `false`.
         * @example
         *
         * function isGreeting(value) {
         *   return /^h(?:i|ello)$/.test(value);
         * }
         *
         * function customizer(objValue, srcValue) {
         *   if (isGreeting(objValue) && isGreeting(srcValue)) {
         *     return true;
         *   }
         * }
         *
         * var object = { 'greeting': 'hello' };
         * var source = { 'greeting': 'hi' };
         *
         * _.isMatchWith(object, source, customizer);
         * // => true
         */
        isMatchWith(object: Object, source: Object, customizer: isMatchWithCustomizer): boolean;
    }


interface LoDashImplicitObjectWrapper<T> {
        /**
         * @see _.isMatchWith
         */
        isMatchWith(source: Object, customizer: isMatchWithCustomizer): boolean;
    }


//_.isNaN
interface LoDashStatic {
        /**
         * Checks if value is NaN.
         *
         * Note: This method is not the same as isNaN which returns true for undefined and other non-numeric values.
         *
         * @param value The value to check.
         * @return Returns true if value is NaN, else false.
         */
        isNaN(value?: any): boolean;
    }


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


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


//_.isNative
interface LoDashStatic {
        /**
         * Checks if value is a native function.
         * @param value The value to check.
         *
         * @retrun Returns true if value is a native function, else false.
         */
        isNative(value: any): value is Function;
    }


interface LoDashImplicitWrapperBase<T, TWrapper> {
        /**
         * see _.isNative
         */
        isNative(): boolean;
    }


interface LoDashExplicitWrapperBase<T, TWrapper> {
        /**
         * see _.isNative
         */
        isNative(): LoDashExplicitWrapper<boolean>;
    }


//_.isNil
interface LoDashStatic {
        /**
         * Checks if `value` is `null` or `undefined`.
         *
         * @static
         * @memberOf _
         * @category Lang
         * @param {*} value The value to check.
         * @returns {boolean} Returns `true` if `value` is nullish, else `false`.
         * @example
         *
         * _.isNil(null);
         * // => true
         *
         * _.isNil(void 0);
         * // => true
         *
         * _.isNil(NaN);
         * // => false
         */
        isNil(value?: any): boolean;
    }


interface LoDashImplicitWrapperBase<T, TWrapper> {
        /**
         * see _.isNil
         */
        isNil(): boolean;
    }


interface LoDashExplicitWrapperBase<T, TWrapper> {
        /**
         * see _.isNil
         */
        isNil(): LoDashExplicitWrapper<boolean>;
    }


//_.isNull
interface LoDashStatic {
        /**
         * Checks if value is null.
         *
         * @param value The value to check.
         * @return Returns true if value is null, else false.
         */
        isNull(value?: any): boolean;
    }


interface LoDashImplicitWrapperBase<T, TWrapper> {
        /**
         * see _.isNull
         */
        isNull(): boolean;
    }


interface LoDashExplicitWrapperBase<T, TWrapper> {
        /**
         * see _.isNull
         */
        isNull(): LoDashExplicitWrapper<boolean>;
    }


//_.isNumber
interface LoDashStatic {
        /**
         * Checks if value is classified as a Number primitive or object.
         *
         * Note: To exclude Infinity, -Infinity, and NaN, which are classified as numbers, use the _.isFinite method.
         *
         * @param value The value to check.
         * @return Returns true if value is correctly classified, else false.
         */
        isNumber(value?: any): value is number;
    }


interface LoDashImplicitWrapperBase<T, TWrapper> {
        /**
         * see _.isNumber
         */
        isNumber(): boolean;
    }


interface LoDashExplicitWrapperBase<T, TWrapper> {
        /**
         * see _.isNumber
         */
        isNumber(): LoDashExplicitWrapper<boolean>;
    }


//_.isObject
interface LoDashStatic {
        /**
         * Checks if value is the language type of Object. (e.g. arrays, functions, objects, regexes, new Number(0),
         * and new String(''))
         *
         * @param value The value to check.
         * @return Returns true if value is an object, else false.
         */
        isObject(value?: any): boolean;
    }


interface LoDashImplicitWrapperBase<T, TWrapper> {
        /**
         * see _.isObject
         */
        isObject(): boolean;
    }


interface LoDashExplicitWrapperBase<T, TWrapper> {
        /**
         * see _.isObject
         */
        isObject(): LoDashExplicitWrapper<boolean>;
    }


//_.isObjectLike
interface LoDashStatic {
        /**
         * Checks if `value` is object-like. A value is object-like if it's not `null`
         * and has a `typeof` result of "object".
         *
         * @static
         * @memberOf _
         * @category Lang
         * @param {*} value The value to check.
         * @returns {boolean} Returns `true` if `value` is object-like, else `false`.
         * @example
         *
         * _.isObjectLike({});
         * // => true
         *
         * _.isObjectLike([1, 2, 3]);
         * // => true
         *
         * _.isObjectLike(_.noop);
         * // => false
         *
         * _.isObjectLike(null);
         * // => false
         */
        isObjectLike(value?: any): boolean;
    }


interface LoDashImplicitWrapperBase<T, TWrapper> {
        /**
         * see _.isObjectLike
         */
        isObjectLike(): boolean;
    }


interface LoDashExplicitWrapperBase<T, TWrapper> {
        /**
         * see _.isObjectLike
         */
        isObjectLike(): LoDashExplicitWrapper<boolean>;
    }


//_.isPlainObject
interface LoDashStatic {
        /**
         * Checks if value is a plain object, that is, an object created by the Object constructor or one with a
         * [[Prototype]] of null.
         *
         * Note: This method assumes objects created by the Object constructor have no inherited enumerable properties.
         *
         * @param value The value to check.
         * @return Returns true if value is a plain object, else false.
         */
        isPlainObject(value?: any): boolean;
    }


interface LoDashImplicitWrapperBase<T, TWrapper> {
        /**
         * see _.isPlainObject
         */
        isPlainObject(): boolean;
    }


interface LoDashExplicitWrapperBase<T, TWrapper> {
        /**
         * see _.isPlainObject
         */
        isPlainObject(): LoDashExplicitWrapper<boolean>;
    }


//_.isRegExp
interface LoDashStatic {
        /**
         * Checks if value is classified as a RegExp object.
         * @param value The value to check.
         *
         * @return Returns true if value is correctly classified, else false.
         */
        isRegExp(value?: any): value is RegExp;
    }


interface LoDashImplicitWrapperBase<T, TWrapper> {
        /**
         * see _.isRegExp
         */
        isRegExp(): boolean;
    }


interface LoDashExplicitWrapperBase<T, TWrapper> {
        /**
         * see _.isRegExp
         */
        isRegExp(): LoDashExplicitWrapper<boolean>;
    }


//_.isSafeInteger
interface LoDashStatic {
        /**
         * Checks if `value` is a safe integer. An integer is safe if it's an IEEE-754
         * double precision number which isn't the result of a rounded unsafe integer.
         *
         * **Note:** This method is based on [`Number.isSafeInteger`](https://mdn.io/Number/isSafeInteger).
         *
         * @static
         * @memberOf _
         * @category Lang
         * @param {*} value The value to check.
         * @returns {boolean} Returns `true` if `value` is a safe integer, else `false`.
         * @example
         *
         * _.isSafeInteger(3);
         * // => true
         *
         * _.isSafeInteger(Number.MIN_VALUE);
         * // => false
         *
         * _.isSafeInteger(Infinity);
         * // => false
         *
         * _.isSafeInteger('3');
         * // => false
         */
        isSafeInteger(value: any): boolean;
    }


interface LoDashImplicitWrapperBase<T, TWrapper> {
        /**
         * see _.isSafeInteger
         */
        isSafeInteger(): boolean;
    }


interface LoDashExplicitWrapperBase<T, TWrapper> {
        /**
         * see _.isSafeInteger
         */
        isSafeInteger(): LoDashExplicitWrapper<boolean>;
    }


//_.isSet
interface LoDashStatic {
        /**
         * Checks if value is classified as a Set object.
         *
         * @param value The value to check.
         * @returns Returns true if value is correctly classified, else false.
         */
        isSet<T>(value?: any): value is Set<T>;
    }


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


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


//_.isString
interface LoDashStatic {
        /**
         * Checks if value is classified as a String primitive or object.
         *
         * @param value The value to check.
         * @return Returns true if value is correctly classified, else false.
         */
        isString(value?: any): value is string;
    }


interface LoDashImplicitWrapperBase<T, TWrapper> {
        /**
         * see _.isString
         */
        isString(): boolean;
    }


interface LoDashExplicitWrapperBase<T, TWrapper> {
        /**
         * see _.isString
         */
        isString(): LoDashExplicitWrapper<boolean>;
    }


//_.isSymbol
interface LoDashStatic {
        /**
         * Checks if `value` is classified as a `Symbol` primitive or object.
         *
         * @static
         * @memberOf _
         * @category Lang
         * @param {*} value The value to check.
         * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
         * @example
         *
         * _.isSymbol(Symbol.iterator);
         * // => true
         *
         * _.isSymbol('abc');
         * // => false
         */
        isSymbol(value: any): boolean;
    }


interface LoDashImplicitWrapperBase<T, TWrapper> {
        /**
         * see _.isSymbol
         */
        isSymbol(): boolean;
    }


interface LoDashExplicitWrapperBase<T, TWrapper> {
        /**
         * see _.isSymbol
         */
        isSymbol(): LoDashExplicitWrapper<boolean>;
    }


//_.isTypedArray
interface LoDashStatic {
        /**
         * Checks if value is classified as a typed array.
         *
         * @param value The value to check.
         * @return Returns true if value is correctly classified, else false.
         */
        isTypedArray(value: any): boolean;
    }


interface LoDashImplicitWrapperBase<T, TWrapper> {
        /**
         * see _.isTypedArray
         */
        isTypedArray(): boolean;
    }


interface LoDashExplicitWrapperBase<T, TWrapper> {
        /**
         * see _.isTypedArray
         */
        isTypedArray(): LoDashExplicitWrapper<boolean>;
    }


//_.isUndefined
interface LoDashStatic {
        /**
         * Checks if value is undefined.
         *
         * @param value The value to check.
         * @return Returns true if value is undefined, else false.
         */
        isUndefined(value: any): boolean;
    }


interface LoDashImplicitWrapperBase<T, TWrapper> {
        /**
         * see _.isUndefined
         */
        isUndefined(): boolean;
    }


interface LoDashExplicitWrapperBase<T, TWrapper> {
        /**
         * see _.isUndefined
         */
        isUndefined(): LoDashExplicitWrapper<boolean>;
    }


//_.isWeakMap
interface LoDashStatic {
        /**
         * Checks if value is classified as a WeakMap object.
         *
         * @param value The value to check.
         * @returns Returns true if value is correctly classified, else false.
         */
        isWeakMap<K, V>(value?: any): value is WeakMap<K, V>;
    }


interface LoDashImplicitWrapperBase<T, TWrapper> {
        /**
         * @see _.isSet
         */
        isWeakMap(): boolean;
    }


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


//_.isWeakSet
interface LoDashStatic {
        /**
         * Checks if value is classified as a WeakSet object.
         *
         * @param value The value to check.
         * @returns Returns true if value is correctly classified, else false.
         */
        isWeakSet<T>(value?: any): value is WeakSet<T>;
    }


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


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


//_.lt
interface LoDashStatic {
        /**
         * Checks if value is less than other.
         *
         * @param value The value to compare.
         * @param other The other value to compare.
         * @return Returns true if value is less than other, else false.
         */
        lt(
            value: any,
            other: any
        ): boolean;
    }


interface LoDashImplicitWrapperBase<T, TWrapper> {
        /**
         * @see _.lt
         */
        lt(other: any): boolean;
    }


interface LoDashExplicitWrapperBase<T, TWrapper> {
        /**
         * @see _.lt
         */
        lt(other: any): LoDashExplicitWrapper<boolean>;
    }


//_.lte
interface LoDashStatic {
        /**
         * Checks if value is less than or equal to other.
         *
         * @param value The value to compare.
         * @param other The other value to compare.
         * @return Returns true if value is less than or equal to other, else false.
         */
        lte(
            value: any,
            other: any
        ): boolean;
    }


interface LoDashImplicitWrapperBase<T, TWrapper> {
        /**
         * @see _.lte
         */
        lte(other: any): boolean;
    }


interface LoDashExplicitWrapperBase<T, TWrapper> {
        /**
         * @see _.lte
         */
        lte(other: any): LoDashExplicitWrapper<boolean>;
    }


//_.toArray
interface LoDashStatic {
        /**
         * Converts value to an array.
         *
         * @param value The value to convert.
         * @return Returns the converted array.
         */
        toArray<T>(value: List<T>|Dictionary<T>|NumericDictionary<T>): T[];

        /**
         * @see _.toArray
         */
        toArray<TValue, TResult>(value: TValue): TResult[];

        /**
         * @see _.toArray
         */
        toArray<TResult>(value?: any): TResult[];
    }


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


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


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


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


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


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


//_.toPlainObject
interface LoDashStatic {
        /**
         * Converts value to a plain object flattening inherited enumerable properties of value to own properties
         * of the plain object.
         *
         * @param value The value to convert.
         * @return Returns the converted plain object.
         */
        toPlainObject<TResult extends {}>(value?: any): TResult;
    }


interface LoDashImplicitWrapperBase<T, TWrapper> {
        /**
         * @see _.toPlainObject
         */
        toPlainObject<TResult extends {}>(): LoDashImplicitObjectWrapper<TResult>;
    }


//_.toInteger
interface LoDashStatic {
        /**
         * Converts `value` to an integer.
         *
         * **Note:** This function is loosely based on [`ToInteger`](http://www.ecma-international.org/ecma-262/6.0/#sec-tointeger).
         *
         * @static
         * @memberOf _
         * @category Lang
         * @param {*} value The value to convert.
         * @returns {number} Returns the converted integer.
         * @example
         *
         * _.toInteger(3);
         * // => 3
         *
         * _.toInteger(Number.MIN_VALUE);
         * // => 0
         *
         * _.toInteger(Infinity);
         * // => 1.7976931348623157e+308
         *
         * _.toInteger('3');
         * // => 3
         */
        toInteger(value: any): number;
    }


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


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


//_.toLength
interface LoDashStatic {
        /**
         * Converts `value` to an integer suitable for use as the length of an
         * array-like object.
         *
         * **Note:** This method is based on [`ToLength`](http://ecma-international.org/ecma-262/6.0/#sec-tolength).
         *
         * @static
         * @memberOf _
         * @category Lang
         * @param {*} value The value to convert.
         * @return {number} Returns the converted integer.
         * @example
         *
         * _.toLength(3);
         * // => 3
         *
         * _.toLength(Number.MIN_VALUE);
         * // => 0
         *
         * _.toLength(Infinity);
         * // => 4294967295
         *
         * _.toLength('3');
         * // => 3
         */
        toLength(value: any): number;
    }


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


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


//_.toNumber
interface LoDashStatic {
        /**
         * Converts `value` to a number.
         *
         * @static
         * @memberOf _
         * @category Lang
         * @param {*} value The value to process.
         * @returns {number} Returns the number.
         * @example
         *
         * _.toNumber(3);
         * // => 3
         *
         * _.toNumber(Number.MIN_VALUE);
         * // => 5e-324
         *
         * _.toNumber(Infinity);
         * // => Infinity
         *
         * _.toNumber('3');
         * // => 3
         */
        toNumber(value: any): number;
    }


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


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


//_.toSafeInteger
interface LoDashStatic {
        /**
         * Converts `value` to a safe integer. A safe integer can be compared and
         * represented correctly.
         *
         * @static
         * @memberOf _
         * @category Lang
         * @param {*} value The value to convert.
         * @returns {number} Returns the converted integer.
         * @example
         *
         * _.toSafeInteger(3);
         * // => 3
         *
         * _.toSafeInteger(Number.MIN_VALUE);
         * // => 0
         *
         * _.toSafeInteger(Infinity);
         * // => 9007199254740991
         *
         * _.toSafeInteger('3');
         * // => 3
         */
        toSafeInteger(value: any): number;
    }


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


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


//_.toString DUMMY
interface LoDashStatic {
        /**
         * Converts `value` to a string if it's not one. An empty string is returned
         * for `null` and `undefined` values. The sign of `-0` is preserved.
         *
         * @static
         * @memberOf _
         * @category Lang
         * @param {*} value The value to process.
         * @returns {string} Returns the string.
         * @example
         *
         * _.toString(null);
         * // => ''
         *
         * _.toString(-0);
         * // => '-0'
         *
         * _.toString([1, 2, 3]);
         * // => '1,2,3'
         */
        toString(value: any): string;
    }


/********
     * Math *
     ********/
//_.add
interface LoDashStatic {
        /**
         * Adds two numbers.
         *
         * @param augend The first number to add.
         * @param addend The second number to add.
         * @return Returns the sum.
         */
        add(
            augend: number,
            addend: number
        ): number;
    }


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


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


//_.ceil
interface LoDashStatic {
        /**
         * Calculates n rounded up to precision.
         *
         * @param n The number to round up.
         * @param precision The precision to round up to.
         * @return Returns the rounded up number.
         */
        ceil(
            n: number,
            precision?: number
        ): number;
    }


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


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


//_.floor
interface LoDashStatic {
        /**
         * Calculates n rounded down to precision.
         *
         * @param n The number to round down.
         * @param precision The precision to round down to.
         * @return Returns the rounded down number.
         */
        floor(
            n: number,
            precision?: number
        ): number;
    }


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


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


//_.max
interface LoDashStatic {
         /**
          * Computes the maximum value of `array`. If `array` is empty or falsey
          * `undefined` is returned.
          *
          * @static
          * @memberOf _
          * @category Math
          * @param {Array} array The array to iterate over.
          * @returns {*} Returns the maximum value.
          */
        max<T>(
            collection: List<T>
        ): T;
    }


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


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


//_.maxBy
interface LoDashStatic {
        /**
         * This method is like `_.max` except that it accepts `iteratee` which is
         * invoked for each element in `array` to generate the criterion by which
         * the value is ranked. The iteratee is invoked with one argument: (value).
         *
         * @static
         * @memberOf _
         * @category Math
         * @param {Array} array The array to iterate over.
         * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element.
         * @returns {*} Returns the maximum value.
         * @example
         *
         * var objects = [{ 'n': 1 }, { 'n': 2 }];
         *
         * _.maxBy(objects, function(o) { return o.a; });
         * // => { 'n': 2 }
         *
         * // using the `_.property` iteratee shorthand
         * _.maxBy(objects, 'n');
         * // => { 'n': 2 }
         */
        maxBy<T>(
            collection: List<T>,
            iteratee?: ListIterator<T, any>
        ): T;

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

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

        /**
         * @see _.maxBy
         */
        maxBy<TObject extends {}, T>(
            collection: List<T>|Dictionary<T>,
            whereValue?: TObject
        ): T;
    }


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

        /**
         * @see _.maxBy
         */
        maxBy(
            iteratee?: string
        ): T;

        /**
         * @see _.maxBy
         */
        maxBy<TObject extends {}>(
            whereValue?: TObject
        ): T;
    }


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

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

        /**
         * @see _.maxBy
         */
        maxBy<TObject extends {}, T>(
            whereValue?: TObject
        ): T;
    }


//_.mean
interface LoDashStatic {
        /**
         * Computes the mean of the values in `array`.
         *
         * @static
         * @memberOf _
         * @category Math
         * @param {Array} array The array to iterate over.
         * @returns {number} Returns the mean.
         * @example
         *
         * _.mean([4, 2, 8, 6]);
         * // => 5
         */
        mean<T>(
            collection: List<T>
        ): number;
    }


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

        /**
         * @see _.mean
         */
        mean(): number;
    }


//_.min
interface LoDashStatic {
        /**
         * Computes the minimum value of `array`. If `array` is empty or falsey
         * `undefined` is returned.
         *
         * @static
         * @memberOf _
         * @category Math
         * @param {Array} array The array to iterate over.
         * @returns {*} Returns the minimum value.
         */
        min<T>(
            collection: List<T>
        ): T;
    }


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


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


//_.minBy
interface LoDashStatic {
        /**
         * This method is like `_.min` except that it accepts `iteratee` which is
         * invoked for each element in `array` to generate the criterion by which
         * the value is ranked. The iteratee is invoked with one argument: (value).
         *
         * @static
         * @memberOf _
         * @category Math
         * @param {Array} array The array to iterate over.
         * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element.
         * @returns {*} Returns the minimum value.
         * @example
         *
         * var objects = [{ 'n': 1 }, { 'n': 2 }];
         *
         * _.minBy(objects, function(o) { return o.a; });
         * // => { 'n': 1 }
         *
         * // using the `_.property` iteratee shorthand
         * _.minBy(objects, 'n');
         * // => { 'n': 1 }
         */
        minBy<T>(
            collection: List<T>,
            iteratee?: ListIterator<T, any>
        ): T;

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

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

        /**
         * @see _.minBy
         */
        minBy<TObject extends {}, T>(
            collection: List<T>|Dictionary<T>,
            whereValue?: TObject
        ): T;
    }


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

        /**
         * @see _.minBy
         */
        minBy(
            iteratee?: string
        ): T;

        /**
         * @see _.minBy
         */
        minBy<TObject extends {}>(
            whereValue?: TObject
        ): T;
    }


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

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

        /**
         * @see _.minBy
         */
        minBy<TObject extends {}, T>(
            whereValue?: TObject
        ): T;
    }


//_.round
interface LoDashStatic {
        /**
         * Calculates n rounded to precision.
         *
         * @param n The number to round.
         * @param precision The precision to round to.
         * @return Returns the rounded number.
         */
        round(
            n: number,
            precision?: number
        ): number;
    }


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


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


//_.sum
interface LoDashStatic {
        /**
         * Computes the sum of the values in `array`.
         *
         * @static
         * @memberOf _
         * @category Math
         * @param {Array} array The array to iterate over.
         * @returns {number} Returns the sum.
         * @example
         *
         * _.sum([4, 2, 8, 6]);
         * // => 20
         */
        sum<T>(collection: List<T>): number;

        /**
         * @see _.sum
         */
        sum(collection: List<number>|Dictionary<number>): number;
    }


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


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

        /**
         * @see _.sum
         */
        sum(): number;
    }


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


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

        /**
         * @see _.sum
         */
        sum(): LoDashExplicitWrapper<number>;
    }


//_.sumBy
interface LoDashStatic {
        /**
         * This method is like `_.sum` except that it accepts `iteratee` which is
         * invoked for each element in `array` to generate the value to be summed.
         * The iteratee is invoked with one argument: (value).
         *
         * @static
         * @memberOf _
         * @category Math
         * @param {Array} array The array to iterate over.
         * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element.
         * @returns {number} Returns the sum.
         * @example
         *
         * var objects = [{ 'n': 4 }, { 'n': 2 }, { 'n': 8 }, { 'n': 6 }];
         *
         * _.sumBy(objects, function(o) { return o.n; });
         * // => 20
         *
         * // using the `_.property` iteratee shorthand
         * _.sumBy(objects, 'n');
         * // => 20
         */
        sumBy<T>(
            collection: List<T>,
            iteratee: ListIterator<T, number>
        ): number;

        /**
         * @see _.sumBy
         **/
        sumBy<T>(
            collection: Dictionary<T>,
            iteratee: DictionaryIterator<T, number>
        ): number;

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

        /**
         * @see _.sumBy
         */
        sumBy<T>(collection: List<T>|Dictionary<T>): number;

        /**
         * @see _.sumBy
         */
        sumBy(collection: List<number>|Dictionary<number>): number;
    }


interface LoDashImplicitArrayWrapper<T> {
        /**
         * @see _.sumBy
         */
        sumBy(
            iteratee: ListIterator<T, number>
        ): number;

        /**
         * @see _.sumBy
         */
        sumBy(iteratee: string): number;

        /**
         * @see _.sumBy
         */
        sumBy(): number;
    }


interface LoDashImplicitObjectWrapper<T> {
        /**
         * @see _.sumBy
         **/
        sumBy<TValue>(
            iteratee: ListIterator<TValue, number>|DictionaryIterator<TValue, number>
        ): number;

        /**
         * @see _.sumBy
         */
        sumBy(iteratee: string): number;

        /**
         * @see _.sumBy
         */
        sumBy(): number;
    }


interface LoDashExplicitArrayWrapper<T> {
        /**
         * @see _.sumBy
         */
        sumBy(
            iteratee: ListIterator<T, number>
        ): LoDashExplicitWrapper<number>;

        /**
         * @see _.sumBy
         */
        sumBy(iteratee: string): LoDashExplicitWrapper<number>;

        /**
         * @see _.sumBy
         */
        sumBy(): LoDashExplicitWrapper<number>;
    }


interface LoDashExplicitObjectWrapper<T> {
        /**
         * @see _.sumBy
         */
        sumBy<TValue>(
            iteratee: ListIterator<TValue, number>|DictionaryIterator<TValue, number>
        ): LoDashExplicitWrapper<number>;

        /**
         * @see _.sumBy
         */
        sumBy(iteratee: string): LoDashExplicitWrapper<number>;

        /**
         * @see _.sumBy
         */
        sumBy(): LoDashExplicitWrapper<number>;
    }


/**********
     * Number *
     **********/
//_.subtract
interface LoDashStatic {
        /**
         * Subtract two numbers.
         *
         * @static
         * @memberOf _
         * @category Math
         * @param {number} minuend The first number in a subtraction.
         * @param {number} subtrahend The second number in a subtraction.
         * @returns {number} Returns the difference.
         * @example
         *
         * _.subtract(6, 4);
         * // => 2
         */
        subtract(
            minuend: number,
            subtrahend: number
        ): number;
    }


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


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


//_.clamp
interface LoDashStatic {
        /**
         * Clamps `number` within the inclusive `lower` and `upper` bounds.
         *
         * @static
         * @memberOf _
         * @category Number
         * @param {number} number The number to clamp.
         * @param {number} [lower] The lower bound.
         * @param {number} upper The upper bound.
         * @returns {number} Returns the clamped number.
         * @example
         *
         * _.clamp(-10, -5, 5);
         * // => -5
         *
         * _.clamp(10, -5, 5);
         * // => 5
         */
        clamp(
            number: number,
            lower: number,
            upper: number
        ): number;
    }


interface LoDashImplicitWrapper<T> {
        /**
         * @see _.clamp
         */
        clamp(
            lower: number,
            upper: number
        ): number;
    }


interface LoDashExplicitWrapper<T> {
        /**
         * @see _.clamp
         */
        clamp(
            lower: number,
            upper: number
        ): LoDashExplicitWrapper<number>;
    }


//_.inRange
interface LoDashStatic {
        /**
         * Checks if n is between start and up to but not including, end. If end is not specified it’s set to start
         * with start then set to 0.
         *
         * @param n The number to check.
         * @param start The start of the range.
         * @param end The end of the range.
         * @return Returns true if n is in the range, else false.
         */
        inRange(
            n: number,
            start: number,
            end: number
        ): boolean;

        /**
         * @see _.inRange
         */
        inRange(
            n: number,
            end: number
        ): boolean;
    }


interface LoDashImplicitWrapper<T> {
        /**
         * @see _.inRange
         */
        inRange(
            start: number,
            end: number
        ): boolean;

        /**
         * @see _.inRange
         */
        inRange(end: number): boolean;
    }


interface LoDashExplicitWrapper<T> {
        /**
         * @see _.inRange
         */
        inRange(
            start: number,
            end: number
        ): LoDashExplicitWrapper<boolean>;

        /**
         * @see _.inRange
         */
        inRange(end: number): LoDashExplicitWrapper<boolean>;
    }


//_.random
interface LoDashStatic {
        /**
         * Produces a random number between min and max (inclusive). If only one argument is provided a number between
         * 0 and the given number is returned. If floating is true, or either min or max are floats, a floating-point
         * number is returned instead of an integer.
         *
         * @param min The minimum possible value.
         * @param max The maximum possible value.
         * @param floating Specify returning a floating-point number.
         * @return Returns the random number.
         */
        random(
            min?: number,
            max?: number,
            floating?: boolean
        ): number;

        /**
         * @see _.random
         */
        random(
            min?: number,
            floating?: boolean
        ): number;

        /**
         * @see _.random
         */
        random(floating?: boolean): number;
    }


interface LoDashImplicitWrapper<T> {
        /**
         * @see _.random
         */
        random(
            max?: number,
            floating?: boolean
        ): number;

        /**
         * @see _.random
         */
        random(floating?: boolean): number;
    }


interface LoDashExplicitWrapper<T> {
        /**
         * @see _.random
         */
        random(
            max?: number,
            floating?: boolean
        ): LoDashExplicitWrapper<number>;

        /**
         * @see _.random
         */
        random(floating?: boolean): LoDashExplicitWrapper<number>;
    }


/**********
     * Object *
     **********/
//_.assign
interface LoDashStatic {
        /**
         * Assigns own enumerable properties of source objects to the destination
         * object. Source objects are applied from left to right. Subsequent sources
         * overwrite property assignments of previous sources.
         *
         * **Note:** This method mutates `object` and is loosely based on
         * [`Object.assign`](https://mdn.io/Object/assign).
         *
         * @static
         * @memberOf _
         * @category Object
         * @param {Object} object The destination object.
         * @param {...Object} [sources] The source objects.
         * @returns {Object} Returns `object`.
         * @example
         *
         * function Foo() {
         *   this.c = 3;
         * }
         *
         * function Bar() {
         *   this.e = 5;
         * }
         *
         * Foo.prototype.d = 4;
         * Bar.prototype.f = 6;
         *
         * _.assign({ 'a': 1 }, new Foo, new Bar);
         * // => { 'a': 1, 'c': 3, 'e': 5 }
         */
        assign<TObject extends {}, TSource extends {}, TResult extends {}>(
            object: TObject,
            source: TSource
        ): TResult;

        /**
         * @see assign
         */
        assign<TObject extends {}, TSource1 extends {}, TSource2 extends {}, TResult extends {}>(
            object: TObject,
            source1: TSource1,
            source2: TSource2
        ): TResult;

        /**
         * @see assign
         */
        assign<TObject extends {}, TSource1 extends {}, TSource2 extends {}, TSource3 extends {}, TResult extends {}>(
            object: TObject,
            source1: TSource1,
            source2: TSource2,
            source3: TSource3
        ): TResult;

        /**
         * @see assign
         */
        assign<TObject extends {}, TSource1 extends {}, TSource2 extends {}, TSource3 extends {}, TSource4 extends {},
            TResult extends {}>
        (
            object: TObject,
            source1: TSource1,
            source2: TSource2,
            source3: TSource3,
            source4: TSource4
        ): TResult;

        /**
         * @see _.assign
         */
        assign<TObject extends {}>(object: TObject): TObject;

        /**
         * @see _.assign
         */
        assign<TObject extends {}, TResult extends {}>(
            object: TObject, ...otherArgs: any[]
        ): TResult;
    }


interface LoDashImplicitObjectWrapper<T> {
        /**
         * @see _.assign
         */
        assign<TSource extends {}, TResult extends {}>(
            source: TSource
        ): LoDashImplicitObjectWrapper<TResult>;

        /**
         * @see assign
         */
        assign<TSource1 extends {}, TSource2 extends {}, TResult extends {}>(
            source1: TSource1,
            source2: TSource2
        ): LoDashImplicitObjectWrapper<TResult>;

        /**
         * @see assign
         */
        assign<TSource1 extends {}, TSource2 extends {}, TSource3 extends {}, TResult extends {}>(
            source1: TSource1,
            source2: TSource2,
            source3: TSource3
        ): LoDashImplicitObjectWrapper<TResult>;

        /**
         * @see assign
         */
        assign<TSource1 extends {}, TSource2 extends {}, TSource3 extends {}, TSource4 extends {}, TResult extends {}>(
            source1: TSource1,
            source2: TSource2,
            source3: TSource3,
            source4: TSource4
        ): LoDashImplicitObjectWrapper<TResult>;

        /**
         * @see _.assign
         */
        assign(): LoDashImplicitObjectWrapper<T>;

        /**
         * @see _.assign
         */
        assign<TResult extends {}>(...otherArgs: any[]): LoDashImplicitObjectWrapper<TResult>;
    }


interface LoDashExplicitObjectWrapper<T> {
        /**
         * @see _.assign
         */
        assign<TSource extends {}, TResult extends {}>(
            source: TSource
        ): LoDashExplicitObjectWrapper<TResult>;

        /**
         * @see assign
         */
        assign<TSource1 extends {}, TSource2 extends {}, TResult extends {}>(
            source1: TSource1,
            source2: TSource2
        ): LoDashExplicitObjectWrapper<TResult>;

        /**
         * @see assign
         */
        assign<TSource1 extends {}, TSource2 extends {}, TSource3 extends {}, TResult extends {}>(
            source1: TSource1,
            source2: TSource2,
            source3: TSource3
        ): LoDashExplicitObjectWrapper<TResult>;

        /**
         * @see assign
         */
        assign<TSource1 extends {}, TSource2 extends {}, TSource3 extends {}, TSource4 extends {}, TResult extends {}>(
            source1: TSource1,
            source2: TSource2,
            source3: TSource3,
            source4: TSource4
        ): LoDashExplicitObjectWrapper<TResult>;

        /**
         * @see _.assign
         */
        assign(): LoDashExplicitObjectWrapper<T>;

        /**
         * @see _.assign
         */
        assign<TResult extends {}>(...otherArgs: any[]): LoDashExplicitObjectWrapper<TResult>;
    }


//_.assignWith
interface AssignCustomizer {
        (objectValue: any, sourceValue: any, key?: string, object?: {}, source?: {}): any;
    }


interface LoDashStatic {
        /**
         * This method is like `_.assign` except that it accepts `customizer` which
         * is invoked to produce the assigned values. If `customizer` returns `undefined`
         * assignment is handled by the method instead. The `customizer` is invoked
         * with five arguments: (objValue, srcValue, key, object, source).
         *
         * **Note:** This method mutates `object`.
         *
         * @static
         * @memberOf _
         * @category Object
         * @param {Object} object The destination object.
         * @param {...Object} sources The source objects.
         * @param {Function} [customizer] The function to customize assigned values.
         * @returns {Object} Returns `object`.
         * @example
         *
         * function customizer(objValue, srcValue) {
         *   return _.isUndefined(objValue) ? srcValue : objValue;
         * }
         *
         * var defaults = _.partialRight(_.assignWith, customizer);
         *
         * defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 });
         * // => { 'a': 1, 'b': 2 }
         */
        assignWith<TObject extends {}, TSource extends {}, TResult extends {}>(
            object: TObject,
            source: TSource,
            customizer: AssignCustomizer
        ): TResult;

        /**
         * @see assignWith
         */
        assignWith<TObject extends {}, TSource1 extends {}, TSource2 extends {}, TResult extends {}>(
            object: TObject,
            source1: TSource1,
            source2: TSource2,
            customizer: AssignCustomizer
        ): TResult;

        /**
         * @see assignWith
         */
        assignWith<TObject extends {}, TSource1 extends {}, TSource2 extends {}, TSource3 extends {}, TResult extends {}>(
            object: TObject,
            source1: TSource1,
            source2: TSource2,
            source3: TSource3,
            customizer: AssignCustomizer
        ): TResult;

        /**
         * @see assignWith
         */
        assignWith<TObject extends {}, TSource1 extends {}, TSource2 extends {}, TSource3 extends {}, TSource4 extends {},
            TResult extends {}>
        (
            object: TObject,
            source1: TSource1,
            source2: TSource2,
            source3: TSource3,
            source4: TSource4,
            customizer: AssignCustomizer
        ): TResult;

        /**
         * @see _.assignWith
         */
        assignWith<TObject extends {}>(object: TObject): TObject;

        /**
         * @see _.assignWith
         */
        assignWith<TObject extends {}, TResult extends {}>(
            object: TObject, ...otherArgs: any[]
        ): TResult;
    }


interface LoDashImplicitObjectWrapper<T> {
        /**
         * @see _.assignWith
         */
        assignWith<TSource extends {}, TResult extends {}>(
            source: TSource,
            customizer: AssignCustomizer
        ): LoDashImplicitObjectWrapper<TResult>;

        /**
         * @see assignWith
         */
        assignWith<TSource1 extends {}, TSource2 extends {}, TResult extends {}>(
            source1: TSource1,
            source2: TSource2,
            customizer: AssignCustomizer
        ): LoDashImplicitObjectWrapper<TResult>;

        /**
         * @see assignWith
         */
        assignWith<TSource1 extends {}, TSource2 extends {}, TSource3 extends {}, TResult extends {}>(
            source1: TSource1,
            source2: TSource2,
            source3: TSource3,
            customizer: AssignCustomizer
        ): LoDashImplicitObjectWrapper<TResult>;

        /**
         * @see assignWith
         */
        assignWith<TSource1 extends {}, TSource2 extends {}, TSource3 extends {}, TSource4 extends {}, TResult extends {}>(
            source1: TSource1,
            source2: TSource2,
            source3: TSource3,
            source4: TSource4,
            customizer: AssignCustomizer
        ): LoDashImplicitObjectWrapper<TResult>;

        /**
         * @see _.assignWith
         */
        assignWith(): LoDashImplicitObjectWrapper<T>;

        /**
         * @see _.assignWith
         */
        assignWith<TResult extends {}>(...otherArgs: any[]): LoDashImplicitObjectWrapper<TResult>;
    }


interface LoDashExplicitObjectWrapper<T> {
        /**
         * @see _.assignWith
         */
        assignWith<TSource extends {}, TResult extends {}>(
            source: TSource,
            customizer: AssignCustomizer
        ): LoDashExplicitObjectWrapper<TResult>;

        /**
         * @see assignWith
         */
        assignWith<TSource1 extends {}, TSource2 extends {}, TResult extends {}>(
            source1: TSource1,
            source2: TSource2,
            customizer: AssignCustomizer
        ): LoDashExplicitObjectWrapper<TResult>;

        /**
         * @see assignWith
         */
        assignWith<TSource1 extends {}, TSource2 extends {}, TSource3 extends {}, TResult extends {}>(
            source1: TSource1,
            source2: TSource2,
            source3: TSource3,
            customizer: AssignCustomizer
        ): LoDashExplicitObjectWrapper<TResult>;

        /**
         * @see assignWith
         */
        assignWith<TSource1 extends {}, TSource2 extends {}, TSource3 extends {}, TSource4 extends {}, TResult extends {}>(
            source1: TSource1,
            source2: TSource2,
            source3: TSource3,
            source4: TSource4,
            customizer: AssignCustomizer
        ): LoDashExplicitObjectWrapper<TResult>;

        /**
         * @see _.assignWith
         */
        assignWith(): LoDashExplicitObjectWrapper<T>;

        /**
         * @see _.assignWith
         */
        assignWith<TResult extends {}>(...otherArgs: any[]): LoDashExplicitObjectWrapper<TResult>;
    }


//_.assignIn
interface LoDashStatic {
        /**
         * This method is like `_.assign` except that it iterates over own and
         * inherited source properties.
         *
         * **Note:** This method mutates `object`.
         *
         * @static
         * @memberOf _
         * @alias extend
         * @category Object
         * @param {Object} object The destination object.
         * @param {...Object} [sources] The source objects.
         * @returns {Object} Returns `object`.
         * @example
         *
         * function Foo() {
         *   this.b = 2;
         * }
         *
         * function Bar() {
         *   this.d = 4;
         * }
         *
         * Foo.prototype.c = 3;
         * Bar.prototype.e = 5;
         *
         * _.assignIn({ 'a': 1 }, new Foo, new Bar);
         * // => { 'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5 }
         */
        assignIn<TObject extends {}, TSource extends {}, TResult extends {}>(
            object: TObject,
            source: TSource
        ): TResult;

        /**
         * @see assignIn
         */
        assignIn<TObject extends {}, TSource1 extends {}, TSource2 extends {}, TResult extends {}>(
            object: TObject,
            source1: TSource1,
            source2: TSource2
        ): TResult;

        /**
         * @see assignIn
         */
        assignIn<TObject extends {}, TSource1 extends {}, TSource2 extends {}, TSource3 extends {}, TResult extends {}>(
            object: TObject,
            source1: TSource1,
            source2: TSource2,
            source3: TSource3
        ): TResult;

        /**
         * @see assignIn
         */
        assignIn<TObject extends {}, TSource1 extends {}, TSource2 extends {}, TSource3 extends {}, TSource4 extends {},
            TResult extends {}>
        (
            object: TObject,
            source1: TSource1,
            source2: TSource2,
            source3: TSource3,
            source4: TSource4
        ): TResult;

        /**
         * @see _.assignIn
         */
        assignIn<TObject extends {}>(object: TObject): TObject;

        /**
         * @see _.assignIn
         */
        assignIn<TObject extends {}, TResult extends {}>(
            object: TObject, ...otherArgs: any[]
        ): TResult;
    }


interface LoDashImplicitObjectWrapper<T> {
        /**
         * @see _.assignIn
         */
        assignIn<TSource extends {}, TResult extends {}>(
            source: TSource
        ): LoDashImplicitObjectWrapper<TResult>;

        /**
         * @see assignIn
         */
        assignIn<TSource1 extends {}, TSource2 extends {}, TResult extends {}>(
            source1: TSource1,
            source2: TSource2
        ): LoDashImplicitObjectWrapper<TResult>;

        /**
         * @see assignIn
         */
        assignIn<TSource1 extends {}, TSource2 extends {}, TSource3 extends {}, TResult extends {}>(
            source1: TSource1,
            source2: TSource2,
            source3: TSource3
        ): LoDashImplicitObjectWrapper<TResult>;

        /**
         * @see assignIn
         */
        assignIn<TSource1 extends {}, TSource2 extends {}, TSource3 extends {}, TSource4 extends {}, TResult extends {}>(
            source1: TSource1,
            source2: TSource2,
            source3: TSource3,
            source4: TSource4
        ): LoDashImplicitObjectWrapper<TResult>;

        /**
         * @see _.assignIn
         */
        assignIn(): LoDashImplicitObjectWrapper<T>;

        /**
         * @see _.assignIn
         */
        assignIn<TResult extends {}>(...otherArgs: any[]): LoDashImplicitObjectWrapper<TResult>;
    }


interface LoDashExplicitObjectWrapper<T> {
        /**
         * @see _.assignIn
         */
        assignIn<TSource extends {}, TResult extends {}>(
            source: TSource
        ): LoDashExplicitObjectWrapper<TResult>;

        /**
         * @see assignIn
         */
        assignIn<TSource1 extends {}, TSource2 extends {}, TResult extends {}>(
            source1: TSource1,
            source2: TSource2
        ): LoDashExplicitObjectWrapper<TResult>;

        /**
         * @see assignIn
         */
        assignIn<TSource1 extends {}, TSource2 extends {}, TSource3 extends {}, TResult extends {}>(
            source1: TSource1,
            source2: TSource2,
            source3: TSource3
        ): LoDashExplicitObjectWrapper<TResult>;

        /**
         * @see assignIn
         */
        assignIn<TSource1 extends {}, TSource2 extends {}, TSource3 extends {}, TSource4 extends {}, TResult extends {}>(
            source1: TSource1,
            source2: TSource2,
            source3: TSource3,
            source4: TSource4
        ): LoDashExplicitObjectWrapper<TResult>;

        /**
         * @see _.assignIn
         */
        assignIn(): LoDashExplicitObjectWrapper<T>;

        /**
         * @see _.assignIn
         */
        assignIn<TResult extends {}>(...otherArgs: any[]): LoDashExplicitObjectWrapper<TResult>;
    }


//_.assignInWith
interface AssignCustomizer {
        (objectValue: any, sourceValue: any, key?: string, object?: {}, source?: {}): any;
    }


interface LoDashStatic {
        /**
         * This method is like `_.assignIn` except that it accepts `customizer` which
         * is invoked to produce the assigned values. If `customizer` returns `undefined`
         * assignment is handled by the method instead. The `customizer` is invoked
         * with five arguments: (objValue, srcValue, key, object, source).
         *
         * **Note:** This method mutates `object`.
         *
         * @static
         * @memberOf _
         * @alias extendWith
         * @category Object
         * @param {Object} object The destination object.
         * @param {...Object} sources The source objects.
         * @param {Function} [customizer] The function to customize assigned values.
         * @returns {Object} Returns `object`.
         * @example
         *
         * function customizer(objValue, srcValue) {
         *   return _.isUndefined(objValue) ? srcValue : objValue;
         * }
         *
         * var defaults = _.partialRight(_.assignInWith, customizer);
         *
         * defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 });
         * // => { 'a': 1, 'b': 2 }
         */
        assignInWith<TObject extends {}, TSource extends {}, TResult extends {}>(
            object: TObject,
            source: TSource,
            customizer: AssignCustomizer
        ): TResult;

        /**
         * @see assignInWith
         */
        assignInWith<TObject extends {}, TSource1 extends {}, TSource2 extends {}, TResult extends {}>(
            object: TObject,
            source1: TSource1,
            source2: TSource2,
            customizer: AssignCustomizer
        ): TResult;

        /**
         * @see assignInWith
         */
        assignInWith<TObject extends {}, TSource1 extends {}, TSource2 extends {}, TSource3 extends {}, TResult extends {}>(
            object: TObject,
            source1: TSource1,
            source2: TSource2,
            source3: TSource3,
            customizer: AssignCustomizer
        ): TResult;

        /**
         * @see assignInWith
         */
        assignInWith<TObject extends {}, TSource1 extends {}, TSource2 extends {}, TSource3 extends {}, TSource4 extends {},
            TResult extends {}>
        (
            object: TObject,
            source1: TSource1,
            source2: TSource2,
            source3: TSource3,
            source4: TSource4,
            customizer: AssignCustomizer
        ): TResult;

        /**
         * @see _.assignInWith
         */
        assignInWith<TObject extends {}>(object: TObject): TObject;

        /**
         * @see _.assignInWith
         */
        assignInWith<TObject extends {}, TResult extends {}>(
            object: TObject, ...otherArgs: any[]
        ): TResult;
    }


interface LoDashImplicitObjectWrapper<T> {
        /**
         * @see _.assignInWith
         */
        assignInWith<TSource extends {}, TResult extends {}>(
            source: TSource,
            customizer: AssignCustomizer
        ): LoDashImplicitObjectWrapper<TResult>;

        /**
         * @see assignInWith
         */
        assignInWith<TSource1 extends {}, TSource2 extends {}, TResult extends {}>(
            source1: TSource1,
            source2: TSource2,
            customizer: AssignCustomizer
        ): LoDashImplicitObjectWrapper<TResult>;

        /**
         * @see assignInWith
         */
        assignInWith<TSource1 extends {}, TSource2 extends {}, TSource3 extends {}, TResult extends {}>(
            source1: TSource1,
            source2: TSource2,
            source3: TSource3,
            customizer: AssignCustomizer
        ): LoDashImplicitObjectWrapper<TResult>;

        /**
         * @see assignInWith
         */
        assignInWith<TSource1 extends {}, TSource2 extends {}, TSource3 extends {}, TSource4 extends {}, TResult extends {}>(
            source1: TSource1,
            source2: TSource2,
            source3: TSource3,
            source4: TSource4,
            customizer: AssignCustomizer
        ): LoDashImplicitObjectWrapper<TResult>;

        /**
         * @see _.assignInWith
         */
        assignInWith(): LoDashImplicitObjectWrapper<T>;

        /**
         * @see _.assignInWith
         */
        assignInWith<TResult extends {}>(...otherArgs: any[]): LoDashImplicitObjectWrapper<TResult>;
    }