import type { AggFn, BoolPredicate, CallbackFn, ComparerFn, MapFn, StrFn } from './aggregates';
import type { CombineFn, IGrouping, IndexIsPredicate, IndexMapFn, IndexPredicate, SortFn } from './iterators';
/**
 * The base class that all lazy iterable objects derive from.
 * This can be extended with custom iterators if needed.
 */
export declare abstract class Lazy<TElement> implements Iterable<TElement> {
    /**
     * Creates an empty lazy iterable.
     * @returns The empty lazy iterable object.
     */
    static empty<TElement>(): Lazy<TElement>;
    /**
     * Creates a lazy iterable object from the given iterable object.
     * @param iterable The object to source for lazy iteration.
     * @returns The lazy iterable object with the given iterable as the source.
     * @remarks If you pass in a lazy iterator, then it is returned without
     * changes.
     */
    static from<TElement>(iterable: Iterable<TElement>): Lazy<TElement>;
    /**
     * Creates a lazy iterable object that will produce a range of integers.
     * @param start The starting number of the range (inclusive).
     * @param end The ending number of the range (exclusive). If not given, then
     * the value is assumed to be +Infinity.
     * @returns The lazy iterable object with the range as the source.
     * @remarks When creating an infinite interable, be very careful. If you do not
     * include your own stop condition (e.g. with `.take(n)`), then it will lock
     * up the thread until the process is aborted. You will also have to take into
     * account that some lazy iterators *require* the interable to be finite to work.
     * Check the remarks on the function you want to use to see which ones will work.
     */
    static range(start: number, end?: number): Lazy<number>;
    /**
     * Creates a lazy iterable object that will repeate the element a given number
     * of times.
     * @param element The value to repeat.
     * @param count The number of times to repeat it. If not given, then the
     * value is assumed to be +Infinity.
     * @returns The lazy iterable object with the repeated value as the source.
     * @throws {Error} If count < 0.
     * @remarks When creating an infinite interable, be very careful. If you do not
     * include your own stop condition (e.g. with `.take(n)`), then it will lock
     * up the thread until the process is aborted. You will also have to take into
     * account that some lazy iterators *require* the interable to be finite to work.
     * Check the remarks on the function you want to use to see which ones will work.
     */
    static repeat<TElement>(element: TElement, count?: number): Lazy<TElement>;
    /**
     * Applies an accumulator function over an interable.
     * @param agg The accumulator function to apply over the iterable.
     * @returns The final accumulator value.
     * @throws {Error} If the iterable was empty.
     * @remarks The function works very similarly to `Array.prototype.reduce`, with
     * the added benefit of working on any general iterable object.
     * This will cause a complete iteration of the iterable object.
     */
    aggregate(agg: AggFn<TElement, TElement>): TElement;
    /**
     * Applies an accumulator function over an interable.
     * @param agg The accumulator function to apply over the iterable.
     * @param seed The seed to set the initial `acc` param to in the accumulator function.
     * If not given, then the first element is used.
     * @returns The final accumulator value.
     * @remarks The function works very similarly to `Array.prototype.reduce`, with
     * the added benefit of working on any general iterable object.
     * This will cause a complete iteration of the iterable object.
     */
    aggregate<TAcc>(agg: AggFn<TElement, TAcc>, seed: TAcc): TAcc;
    /**
     * Returns whether all elements satisfy the given condition.
     * @param predicate The function to use to test each element.
     * @returns Whether all elements satisfied the condition.
     * @remarks This will iterate until the condition is false or until the iterable
     * ends.
     */
    all(predicate: BoolPredicate<TElement>): boolean;
    /**
     * Returns whether the iterable is not empty.
     * @returns Whether the iterable is not empty.
     * @remarks For checking whether the given lazy query has any elements, prefer to use
     * this function over [[Lazy.count]], as that function will iterate the entire
     * object, whereas this will stop at the first.
     * This will iterate only a single time.
     */
    any(): boolean;
    /**
     * Returns whether any of the elements satisfy the given condition.
     * @param predicate The function to use to test each element.
     * @returns Whether any element in the iterable satisfied the condition.
     * If the iterable was empty, then `false` is returned
     * @remarks For checking whether the given lazy query has any elements, prefer to use
     * this function over [[Lazy.count]], as that function will iterate the entire
     * object, whereas this will stop at the first element that satisfies the condition.
     * This will iterate until the condition is true or until the iterable ends.
     */
    any(predicate: BoolPredicate<TElement>): boolean;
    /**
     * Computes the average of the iterable.
     * @returns The numeric average of the iterable.
     * @throws {TypeError} If any element in the iterable was a non-number.
     * @throws {Error} If the iterable was empty.
     * @remarks This will cause a complete iteration of the iterable object.
     */
    average(): TElement extends number ? number : never;
    /**
     * Computes the average of result of the selector function over the iterable.
     * @param selector The transformation function to use for each element.
     * @returns The numeric average of the results of the selector function.
     * @throws {Error} If the iterable was empty.
     * @remarks This will cause a complete iteration of the iterable object.
     */
    average(selector: MapFn<TElement, number>): number;
    /**
     * Determines whether the iterable has a given element.
     * @param element The value to search for.
     * @param comparer The function that compares 2 elements and returns a boolean on whether they
     * are equal or not. If not given, defaults to strict equals (`===`).
     * @returns Whether the element was in the iterable.
     * @remarks This will iterable until the given value is found, or until the
     * iterable ends.
     */
    contains(element: TElement, comparer?: ComparerFn<TElement>): boolean;
    /**
     * Returns the number of elements in the iterable.
     * @returns The number of elements in the iterable.
     * @remarks To determine whether an iterable has any elements, prefer the
     * [[Lazy.any]] method, as this will iterate the entire iterable regardless.
     * This will cause a complete iteration of the iterable object.
     */
    count(): number;
    /**
     * Returns the number of elements that satify the given condition.
     * @param predicate The predicate to test each element with.
     * @returns The number of elements in the iterable that matched the condition.
     * @remarks To determine whether an iterable has any elements, prefer the
     * [[Lazy.any]] method, as this will iterate the entire iterable regardless.
     * This will cause a complete iteration of the iterable object.
     */
    count(predicate: BoolPredicate<TElement>): number;
    /**
     * Returns the element at the given index of the iterable.
     * @param index The index of the element to get.
     * @returns The element at the given index.
     * @throws {Error} If the index was < 0 or if it is >= the length of the iterable.
     * @remarks The will iterate until the specified index, or until the iterable
     * ends.
     */
    elementAt(index: number): TElement;
    /**
     * Returns the element at the given index of the iterable, or the given default
     * value if out of range.
     * @param index The index of the element to get.
     * @param defaultValue The default value to use if the index was out of range.
     * @returns The element at the given index.
     * @remarks This will iterable until the specified index, or unitl the iterable
     * ends.
     */
    elementAtOrDefault(index: number, defaultValue: TElement): TElement;
    /**
     * Returns the element at the given index of the iterable, or the given default
     * value if out of range.
     * @param index The index of the element to get.
     * @param defaultValue The default value to use if the index was out of range.
     * @returns The element at the given index.
     * @remarks This will iterable until the specified index, or unitl the iterable
     * ends.
     */
    elementAtOrDefault<TDefault>(index: number, defaultValue: TDefault): TElement | TDefault;
    /**
     * Returns the first element in the iterable.
     * @returns The first element in the iterable.
     * @throws {Error} If the iterable was empty.
     * @remarks This will only iterate a single time.
     */
    first(): TElement;
    /**
     * Returns the first element that satisfies the given condition.
     * @param predicate The predicate to test each element with.
     * @returns The first element in the iterable that satisfies the condition.
     * @throws {Error} If the iterable was empty.
     * @remarks This will iterate until the condition is satisfied, or until the
     * iterable ends.
     */
    first(predicate: BoolPredicate<TElement>): TElement;
    /**
     * Returns the first element in the iterable, or the given default value if
     * the iterable was empty.
     * @param defaultValue The value to use of the iterable was empty.
     * @returns The first element in the iterable, or the default value if empty.
     * @remarks This will only iterate a single time.
     */
    firstOrDefault(defaultValue: TElement): TElement;
    /**
     * Returns the first element in the iterable, or the given default value if
     * the iterable was empty.
     * @param defaultValue The value to use of the iterable was empty.
     * @returns The first element in the iterable, or the default value if empty.
     * @remarks This will only iterate a single time.
     */
    firstOrDefault<TDefault>(defaultValue: TDefault): TElement | TDefault;
    /**
     * Returns the first element in the iterable that satisfies the condition,
     * or the given default value.
     * @param defaultValue The value to use if no element satisfied the condition.
     * @param predicate The predicate to test each element with.
     * @returns The first element in the iterable that satisfies the condition,
     * or the default value if none satisfied it.
     * @remarks This will iterate until the condition is satisfied, or until the
     * iterable ends.
     */
    firstOrDefault(defaultValue: TElement, predicate: BoolPredicate<TElement>): TElement;
    /**
     * Returns the first element in the iterable that satisfies the condition,
     * or the given default value.
     * @param defaultValue The value to use if no element satisfied the condition.
     * @param predicate The predicate to test each element with.
     * @returns The first element in the iterable that satisfies the condition,
     * or the default value if none satisfied it.
     * @remarks This will iterate until the condition is satisfied, or until the
     * iterable ends.
     */
    firstOrDefault<TDefault>(defaultValue: TDefault, predicate: BoolPredicate<TElement>): TElement | TDefault;
    /**
     * Mimics the behaviour of `Array.prototype.forEach`, with the exception
     * of not providing the entire array as the 3rd param of the callback.
     * @param callbackFn The callback function that will be executed for each element
     * in the iterable.
     * @remarks This will cause a complete iteration of the iterable object.
     */
    forEach(callbackFn: CallbackFn<TElement>): void;
    /**
     * Determines whether 2 iterables are equal.
     * @param second The iterable to compare against.
     * @param comparer The function to perform the comparision of each pair of
     * elements with. If not given, defaults to strict equals (`===`).
     * @returns Whether the 2 iterables were both equal.
     * @remarks This will check for both order and value, and will iterate
     * both iterables completely.
     */
    iterableEquals(second: Iterable<TElement>, comparer?: ComparerFn<TElement>): boolean;
    /**
     * Returns the last element in the iterable.
     * @returns The last element in the iterable.
     * @throws {Error} If the iterable was empty.
     * @remarks This will cause a complete iteration of the iterable object.
     */
    last(): TElement;
    /**
     * Returns the last element in the iterable that satisfies the given condition.
     * @param predicate The predicate to test each element with.
     * @returns The last element in the iterable that satisfied the condition.
     * @throws {Error} If no elements satisfied the condition.
     * @remarks This will cause a complete iteration of the iterable object.
     */
    last(predicate: BoolPredicate<TElement>): TElement;
    /**
     * Returns the last element in the iterable, or the given default value if
     * the iterable was empty.
     * @param defaultValue The value to use of the iterable was empty.
     * @returns The last element in the iterable, or the default value if empty.
     * @remarks This will cause a complete iteration of the iterable object.
     */
    lastOrDefault(defaultValue: TElement): TElement;
    /**
     * Returns the last element in the iterable, or the given default value if
     * the iterable was empty.
     * @param defaultValue The value to use of the iterable was empty.
     * @returns The last element in the iterable, or the default value if empty.
     * @remarks This will cause a complete iteration of the iterable object.
     */
    lastOrDefault<TDefault>(defaultValue: TDefault): TElement | TDefault;
    /**
     * Returns the last element in the iterable that satisfies the given condition,
     * or the given default value.
     * @param defaultValue The value to use of the iterable was empty.
     * @param predicate The predicate to test each element with.
     * @returns The last element in the iterable, or the default value if no element
     * satisfied the condition.
     * @remarks This will cause a complete iteration of the iterable object.
     */
    lastOrDefault(defaultValue: TElement, predicate: BoolPredicate<TElement>): TElement;
    /**
     * Returns the last element in the iterable that satisfies the given condition,
     * or the given default value.
     * @param defaultValue The value to use of the iterable was empty.
     * @param predicate The predicate to test each element with.
     * @returns The last element in the iterable, or the default value if no element
     * satisfied the condition.
     * @remarks This will cause a complete iteration of the iterable object.
     */
    lastOrDefault<TDefault>(defaultValue: TDefault, predicate: BoolPredicate<TElement>): TElement | TDefault;
    /**
     * Returns the maximum value in the iterable.
     * @returns The maximum element.
     * @throws {TypeError} If any element in the iterable was a non-number.
     * @throws {Error} If the iterable was empty.
     * @remarks This will cause a complete iteration of the iterable object.
     */
    max(): TElement extends number ? number : never;
    /**
     * Returns the maximum value of result of the selector function over the iterable.
     * @param selector The transformation function to use for each element.
     * @returns The maximum result of the selector function.
     * @throws {Error} If the iterable was empty.
     * @remarks This will cause a complete iteration of the iterable object.
     */
    max(selector: MapFn<TElement, number>): number;
    /**
     * Returns the minimum value in the iterable.
     * @returns The minimum element.
     * @throws {TypeError} If any element in the iterable was a non-number.
     * @throws {Error} If the iterable was empty.
     * @remarks This will cause a complete iteration of the iterable object.
     */
    min(): TElement extends number ? number : never;
    /**
     * Returns the minimum value of result of the selector function over the iterable.
     * @param selector The transformation function to use for each element.
     * @returns The minimum result of the selector function.
     * @throws {Error} If the iterable was empty.
     * @remarks This will cause a complete iteration of the iterable object.
     */
    min(selector: MapFn<TElement, number>): number;
    /**
     * Resolves all of the promises in the iterable, and returns a new Lazy
     * iterable from the result.
     * @returns A promise that will resolve to a lazy iterable object.
     * @remarks This will cause a complete iteration of the iterable object.
     * This will behave similar to [[cache]], in that the original lazy iterable
     * will be resolved completely and then discarded, in favour of the resolved
     * iterable.
     */
    resolveAll(): Promise<TElement extends PromiseLike<infer TResult> ? Lazy<TResult> : Lazy<TElement>>;
    /**
     * Returns a single element from the iterable that matches the given
     * condition.
     * @param predicate The predicate function to test each element with.
     * @returns The element that satisfies the condition.
     * @throws {Error} If no element could be found that matched the condition.
     * @remarks This will iterate until the condition is met or until the iterable
     * ends.
     */
    single(predicate: BoolPredicate<TElement>): TElement;
    /**
     * Returns a single element from the iterable that matches the given
     * condition, or a default value if no element was found.
     * @param predicate The predicate function to test each element with.
     * @param defaultValue The default value to use if no element could be found.
     * @returns The element that satisfies the condition, or the default value
     * if no element was found.
     * @remarks This will iterate until the condition is met or until the iterable
     * ends.
     */
    singleOrDefault(predicate: BoolPredicate<TElement>, defaultValue: TElement): TElement;
    /**
     * Returns a single element from the iterable that matches the given
     * condition, or a default value if no element was found.
     * @param predicate The predicate function to test each element with.
     * @param defaultValue The default value to use if no element could be found.
     * @returns The element that satisfies the condition, or the default value
     * if no element was found.
     * @remarks This will iterate until the condition is met or until the iterable
     * ends.
     */
    singleOrDefault<TDefault>(predicate: BoolPredicate<TElement>, defaultValue: TDefault): TElement | TDefault;
    /**
     * Joins all the elements in the iterable together into a single string,
     * split by the given separator.
     * @param separator The separator to split each element with in the string.
     * Defaults to `''`.
     * @param strFn The function to convert each element into a string.
     * @remarks This will cause a complete iteration of the iterable object.
     */
    stringJoin(separator?: string, strFn?: StrFn<TElement>): string;
    /**
     * Computes the sum of all the elements in the iterable.
     * @returns The sum of all the elements.
     * @throws {TypeError} If any element in the iterable was a non-number.
     * @remarks This will cause a complete iteration of the iterable object.
     */
    sum(): TElement extends number ? number : never;
    /**
     * Returns the sum of all the results of the selector function over the iterable.
     * @param selector The transformation function to use for each element.
     * @returns The sum of the results of the selector function.
     * @throws {Error} If the iterable was empty.
     * @remarks This will cause a complete iteration of the iterable object.
     */
    sum(selector: MapFn<TElement, number>): number;
    /**
     * Converts the iterable into a standard JavaScript `Array`.
     * @remarks This will cause a complete iteration of the iterable object.
     */
    toArray(): TElement[];
    /**
     * Converts the iterable to a JSON-serialisable array.
     * @remarks This will cause a complete iteration of the iterable object.
     * This will not do anything to the elements, meaning that you are
     * responsible for ensuring that they are all JSON-serialisable.
     */
    toJSON(): TElement[];
    /**
     * Converts the iterable into a map using the key and value function.
     * @param keyFn The function to use to derive the key of each map element.
     * @param valueFn The function to use to derive the value of map value. If
     * not given, then the value itself is used.
     * @returns A `Map<TKey, TResult>` derived from the iterable.
     * @remarks This will cause a complete iteration of the iterable object.
     */
    toMap<TKey, TResult = TElement>(keyFn: MapFn<TElement, TKey>, valueFn?: MapFn<TElement, TResult>): Map<TKey, TResult>;
    /**
     * Appends the element to the end of the iterable.
     * @param element The element to append.
     * @remarks Does not cause additional unexpected iteration.
     */
    append(element: TElement): Lazy<TElement>;
    /**
     * Applies the given lazy iterable implementation to the current object.
     * This allows for using custom Lazy implementations using the standard
     * chaining syntax.
     * @param fn The function that will create the iterable instance using
     * the current object.
     * @returns The instantiated iterable object.
     */
    apply<TLazy extends Lazy<TResult>, TResult = TElement>(fn: (t: Lazy<TElement>) => TLazy): Lazy<TResult>;
    /**
     * Batches elements in groups of the given batch size.
     * @param batchSize The size of each batch.
     * @param includeIncomplete Whether to include batches
     * that are smaller than the target size. This only applies
     * to the final batch of the iterable if the total size is
     * not a multiple of the batch size.
     * @remarks Does not cause additional unexpected iteration.
     */
    batchIn(batchSize: number, includeIncomplete?: boolean): Lazy<Iterable<TElement>>;
    /**
     * Resolves the underlaying iterable completely and returns a lazy
     * of the result.
     * @remarks This will completely iterate the underlaying iterable,
     * and return a completely new lazy object of the result. This allows
     * for some optimisation when a chain has become complex and iteration
     * of it is needed multiple times (as the resulting iterable will only be
     * calulated once, and then reused). This can also be used to ensure
     * that side-effects of the chain are only done once, which can be useful
     * in more complicated computations.
     * Since this will return a completely new Lazy iterable, it means that,
     * if no other references exist, then the previous chain (and even the
     * original iterable) can be freed for garbage collection, potentially
     * helping with memory.
     */
    cache(): Lazy<TElement>;
    /**
     * Concatinates multiple iterables in order.
     * @param iterables The other iterables to concatinate with.
     * @remarks Does not cause additional unexpected iteration.
     */
    concat(...iterables: Array<Iterable<TElement>>): Lazy<TElement>;
    /**
     * Returns the elements in the iterable, or the given default value
     * as the only element if it contained none.
     * @param defaultValue The value to use if the iterable was empty.
     * @remarks Does not cause additional unexpected iteration.
     */
    defaultIfEmpty(defaultValue: TElement): Lazy<TElement>;
    /**
     * Returns the distinct elements in the iterable.
     * @param compareOn A mapping function to get the key to compare with. The result
     * will be effectively compared using a strict equals (`===`) against the others.
     * If not given, then each element will used directly.
     * @remarks Does not cause additional unexpected iteration.
     */
    distinct<TKey>(compareOn?: MapFn<TElement, TKey>): Lazy<TElement>;
    /**
     * Returns the set difference between 2 iterables. This like doing an XOR
     * over the 2 iterables.
     * @param second The iterable to get the difference of.
     * @param compareOn A mapping function to get the key to compare with. The value
     * will be effectively compared using a strict equals (`===`) againt the others.
     * If not given, then each element will used directly.
     * @remarks This will iterate the second iterable completely once it has
     * started iteration (not before). It will not cause additional unexpected iteration
     * on the underlying iterable.
     */
    except<TKey = TElement>(second: Iterable<TElement>, compareOn?: MapFn<TElement, TKey>): Lazy<TElement>;
    /**
     * Groups the elements by key.
     * @param keyFn The function to extract the key from each element.
     * @remarks When this is iterated (not before), the underlying iterator is walked through
     * completely.
     */
    groupBy<TKey>(keyFn: MapFn<TElement, TKey>): Lazy<IGrouping<TKey, TElement>>;
    /**
     * Groups the elements by key and projects each element using the given function.
     * @param keyFn The function to extract the key from each element.
     * @param elementSelector The transformation function to use for each element.
     * @remarks When this is iterated (not before), the underlying iterator is walked through
     * completely.
     */
    groupBy<TKey, TItem>(keyFn: MapFn<TElement, TKey>, elementSelector: MapFn<TElement, TItem>): Lazy<IGrouping<TKey, TItem>>;
    /**
     * Groups the elements by key and projects each element using the given function.
     * The elements of each group are projected using the given function.
     * @param keyFn The function to extract the key from each element.
     * @param elementSelector The transformation function to use for each element.
     * @param resultSelector The transformation function to create the result elements with.
     * @remarks When this is iterated (not before), the underlying iterator is walked through
     * completely.
     */
    groupBy<TKey, TItem, TResult>(keyFn: MapFn<TElement, TKey>, elementSelector: MapFn<TElement, TItem>, resultSelector: CombineFn<TKey, Iterable<TItem>, TResult>): Lazy<TResult>;
    /**
     * Joins 2 iterables on the given key and groups the results.
     * @param second The other iterable to group join with.
     * @param firstKeyFn The function that extracts the key from an element
     * of the first iterable.
     * @param secondKeyFn The function that extracts the key from an element
     * of the second iterable.
     * @param joinFn The function that takes an element from the first and an
     * iterable of elements from the second, and outputs the resulting element.
     * @remarks This will iterate the second iterable completely once it has
     * started iteration (not before). It will not cause additional unexpected iteration
     * on the underlying iterable.
     */
    groupJoin<TSecond, TKey, TResult>(second: Iterable<TSecond>, firstKeyFn: MapFn<TElement, TKey>, secondKeyFn: MapFn<TSecond, TKey>, joinFn: CombineFn<TElement, Iterable<TSecond>, TResult>): Lazy<TResult>;
    /**
     * Returns the set intersection between 2 iterables. This like doing an AND
     * over the 2 iterables.
     * @param second The iterable to get the intersection of.
     * @param compareOn A mapping function to get the key to compare with. The value
     * will be effectively compared using a strict equals (`===`) against the others.
     * If not given, then each element will used directly.
     * @remarks This will iterate the second iterable completely once it has
     * started iteration (not before). It will not cause additional unexpected iteration
     * on the underlying iterable.
     */
    intersect<TKey = TElement>(second: Iterable<TElement>, compareOn?: MapFn<TElement, TKey>): Lazy<TElement>;
    /**
     * Joins 2 iterables on the given matching keys. This is similar to a JOIN in
     * SQL.
     * @param second The iterable to join.
     * @param firstKeyFn The function that extracts the key from the first iterable.
     * @param secondKeyFn The function that extracts the key from the second iterable.
     * @param joinFn The function that takes in a single element from the from each of
     * the first and second iterables, and outputs the resulting element.
     * @remarks This will iterate the second iterable completely once it has
     * started iteration (not before). It will not cause additional unexpected iteration
     * on the underlying iterable.
     */
    join<TSecond, TKey, TResult>(second: Iterable<TSecond>, firstKeyFn: MapFn<TElement, TKey>, secondKeyFn: MapFn<TSecond, TKey>, joinFn: CombineFn<TElement, TSecond, TResult>): Lazy<TResult>;
    /**
     * Sorts the iterable in ascending order.
     * @param keyFn The function used to get the key from a given element.
     * @param compareFn The function that is passed to `Array.prototype.sort` to
     * compare values and return the comparison number. If not given, a default
     * sorting function will be used. This sorting function will match the
     * behaviour of the standard sort comparison function.
     * @remarks When this is iterated (not before), the underlying iterator is walked through
     * completely in order to allow sorting.
     */
    orderBy<TKey>(keyFn: MapFn<TElement, TKey>, compareFn?: SortFn<TKey>): Lazy<TElement>;
    /**
     * Sorts the iterable in descending order.
     * @param keyFn The function used to get the key from a given element.
     * @param compareFn The function that is passed to `Array.prototype.sort` to
     * compare values and return the comparison number. If not given, a default
     * sorting function will be used. This sorting function will match the
     * behaviour of the standard sort comparison function.
     * @remarks When this is iterated (not before), the underlying iterator is walked through
     * completely in order to allow sorting.
     */
    orderByDecending<TKey>(keyFn: MapFn<TElement, TKey>, compareFn?: SortFn<TKey>): Lazy<TElement>;
    /**
     * Sorts the iterable in acending order according to the numeric
     * result of the key function.
     * @param keyFn The function user to get the key from the given element.
     * @remarks When this is iterated (not before), the underlying iterator is walked through
     * completely in order to allow sorting.
     * This function is equivalent to [[orderBy]] with a numeric comparison
     * compare function.
     */
    orderNumericallyBy(keyFn: MapFn<TElement, number>): Lazy<TElement>;
    /**
     * Sorts the iterable in descending order according to the numeric
     * result of the key function.
     * @param keyFn The function used to get the key from a given element.
     * @remarks When this is iterated (not before), the underlying iterator is walked through
     * completely in order to allow sorting.
     * This function is equivalent to [[orderByDecending]] with a numeric comparison
     * compare function.
     */
    orderNumericallyByDecending(keyFn: MapFn<TElement, number>): Lazy<TElement>;
    /**
     * Prepends the element to the beginning of the iterable.
     * @param element The element to prepend.
     * @remarks Does not cause additional unexpected iteration.
     */
    prepend(element: TElement): Lazy<TElement>;
    /**
     * Reverses the order of the iterable.
     * @remarks When this is iterated (not before), the underlying iterator is walked through
     * completely in order to allow starting from the end.
     */
    reverse(): Lazy<TElement>;
    /**
     * Projects the elements of the iterable into a new form.
     * @param selector The transformation function to use for each element.
     * @remarks Does not cause additional unexpected iteration.
     */
    select<TResult>(selector: IndexMapFn<TElement, TResult>): Lazy<TResult>;
    /**
     * Projects the elements of the iterable into a new form, and flattens the iterable of iterables
     * into a single iterable.
     * @param selector The transformation function to use for each element. The index parameter
     * is the index that the element was at in the source iterable, *not* the resulting one.
     * @remarks Does not cause additional unexpected iteration.
     */
    selectMany<TResult>(selector: IndexMapFn<TElement, Iterable<TResult>>): Lazy<TResult>;
    /**
     * Skips the given number of elements from the start of the iterable and returns
     * the rest.
     * @param count The number of elements to skip.
     * @remarks Does not cause additional unexpected iteration.
     */
    skip(count: number): Lazy<TElement>;
    /**
     * Skips the given number of elements from the end of the iterable, returning the rest.
     * @param count The number of elements to skip from the end.
     * @remarks This iterator requires the iterable to be finite in length. It will iterate
     * slightly ahead of the resulting iterable.
     */
    skipLast(count: number): Lazy<TElement>;
    /**
     * Skips all elements in the iterable until the condition returns true, after which all
     * elements are returned regardless.
     * @param predicate The predicate function to check the condition with.
     * @remarks Does not cause additional unexpected iteration.
     */
    skipWhile(predicate: IndexPredicate<TElement>): Lazy<TElement>;
    /**
     * Returns the given number of elements from the start of the iterable, ignoring
     * the rest.
     * @param count The number of elements to take from the start.
     * @remarks Does not cause additional unexpected iteration.
     */
    take(count: number): Lazy<TElement>;
    /**
     * Returns the given number of elements from the end of the iterable, ignore the
     * elements before.
     * @remarks This iterator requires the iterable to be finite in length. It will iterate
     * until the end.
     */
    takeLast(count: number): Lazy<TElement>;
    /**
     * Takes all elements in the iterable until the condition returns true, after which
     * the iterable is considered to have ended.
     * @param predicate The predicate function to check the condition with.
     * @remarks Does not cause additional unexpected iteration.
     */
    takeWhile(predicate: IndexPredicate<TElement>): Lazy<TElement>;
    /**
     * Returns the set union between 2 iterables. This like doing an OR
     * over the 2 iterables.
     * @param second The iterable to get the union of.
     * @param compareOn A mapping function to get the key to compare with. The value
     * will be effectively compared using a strict equals (`===`) against the others.
     * If not given, then the element will used directly.
     * @remarks This will iterate the second iterable completely once it has
     * started iteration (not before). It will not cause additional unexpected iteration
     * on the underlying iterable.
     */
    union<TKey = TElement>(second: Iterable<TElement>, compareOn?: MapFn<TElement, TKey>): Lazy<TElement>;
    /**
     * Filters elements based on the given predicate.
     * @param predicate The predicate function to filter elements with.
     * @remarks Does not cause additional unexpected iteration.
     */
    where<TResult extends TElement>(predicate: IndexIsPredicate<TElement, TResult>): Lazy<TResult>;
    /**
     * Filters elements based on the given predicate.
     * @param predicate The predicate function to filter elements with.
     * @remarks Does not cause additional unexpected iteration.
     */
    where(predicate: IndexPredicate<TElement>): Lazy<TElement>;
    /**
     * Combines 2 iterables into an iterable of tuples. This will merge elements
     * on the same index, finishing on the iterable that finishes first. If the
     * first iterable has 3 elements, and the second 4, then the result will
     * have 3 elements.
     * @param second The iterable to zip with.
     * @remarks Does not cause additional unexpected iteration.
     */
    zip<TSecond>(second: Iterable<TSecond>): Lazy<[TElement, TSecond]>;
    /**
     * Combines 2 iterables using the given selector. This will merge elements
     * on the same index, finishing on the iterable that finishes first. If the
     * first iterable has 3 elements, and the second 4, then the result will
     * have 3 elements.
     * @param second The iterable to zip with.
     * @param selector The function to combine the iterables with.
     * @remarks Does not cause additional unexpected iteration.
     */
    zip<TSecond, TResult>(second: Iterable<TSecond>, selector: CombineFn<TElement, TSecond, TResult>): Lazy<TResult>;
    abstract [Symbol.iterator](): Iterator<TElement>;
}
//# sourceMappingURL=lazy.d.ts.map