import type { InspectOptions } from "util";
import { ListNode } from "./node";
export type { ListNode };
export type ListValue<L extends List<unknown>> = L extends List<infer R> ? R : never;
export type ListTest<T> = (value: T, index: number, self: List<T>, node: ListNode<T>) => boolean;
declare const inspectSym: unique symbol;
type InspectFn = (subject: unknown, opts: InspectOptions) => string;
export declare class List<T> {
    #private;
    constructor(from?: Iterable<T>);
    /**
     * Checks if an object (or any other value) is a List
     * @param list Object that may be a list
     * @returns boolean
     */
    static isList(list: any): list is List<any>;
    /**
     * First value of the List
     */
    get head(): T | undefined;
    /**
     * Last value of the List
     */
    get tail(): T | undefined;
    /**
     * Current length of the List
     */
    get length(): number;
    /**
     * Adds value to the end of the List.
     * Further methods can be chained after this method.
     * @param value Value to add
     * @returns `this` Reference
     */
    push(value: T): this;
    /**
     * Removes the last element from the List and returns it.
     * If the List is empty `undefined` is returned.
     * @returns Value or `undefined`
     */
    pop(): T | undefined;
    /**
     * Removes the first element from the List and returns it.
     * If the List is empty `undefined` is returned.
     * @returns Value or `undefined`
     */
    shift(): T | undefined;
    /**
     * Adds value to the start of the List.
     * Further methods can be chained after this method.
     * @param value Value to add
     * @returns `this` Reference
     */
    unshift(value: T): this;
    /**
     * Gets `ListNode` at specific index. If the index is outside of the
     * range of the List `undefined` is returned.
     * @param n Index of the element
     * @returns `ListNode` or `undefined`
     */
    private getNode;
    /**
     * Gets value at specific index. If the index is outside of the range
     * of the List `undefined` is returned.
     * @param index Index of the element
     * @returns Value or `undefined`
     */
    get(index: number): T | undefined;
    /**
     * Sets value at specific index and returns `true`. If the index is
     * outside of the range of the List `false` is returned.
     * If the index would correspond to the next new element this method
     * acts as an alias to `push`.
     * @param index Index of the element to set
     * @param value Value to set
     * @returns boolean
     */
    set(index: number, value: T): boolean;
    /**
     * Inserts value at index and returns `true`. If the index is outside
     * of the range of the List `false` is returned.
     * If the index would correspond to the next new element this method
     * acts as an alias to `push`.
     * @param index Index of where to insert the new element
     * @param value Value of the new element
     * @returns boolean
     */
    insert(index: number, value: T): boolean;
    /**
     * Removes one or more elements starting at a given index and returns
     * `true`. If the index is outside the range of the List or a amount
     * smaller than one is given `false` is returned.
     * @param index Index at which to remove element(s)
     * @param amount (optional) Amount of elements to remove (default: 1)
     * @returns boolean
     */
    remove(index: number, amount?: number): boolean;
    /**
     * Creates Array with all List values in order.
     * @returns Array
     */
    toArray(): T[];
    /**
     * Inserts all values from another iterable (List, Array, etc.) into List at a
     * given index. If the index is out of range values will be inserted at the
     * start or end of the List as applicable.
     * @param index
     * @param iterable
     * @returns `this` Reference
     */
    insertMany(index: number, iterable: Iterable<T>): this;
    /**
     * Creates a copy of the current List
     * @returns new List
     */
    clone(): List<T>;
    /**
     * Combines List or Array with current List. The existing List is not modified.
     * @param value List or Array of Values
     * @returns new List
     */
    concat(value: Iterable<T>): List<T>;
    /**
     * Checks if a test callback returns `true` for every value
     * @param callback Test callback
     * @returns boolean
     */
    every(callback: ListTest<T>): boolean;
    /**
     * Checks if a test callback returns `true` for at least one value
     * @param callback Test callback
     * @returns boolean
     */
    some(callback: ListTest<T>): boolean;
    /**
     * Creates new list with only the values that the test callback
     * returns `true` for.
     * @param callback Test callback
     * @returns Filtered List
     */
    filter(callback: ListTest<T>): List<T>;
    /**
     * Finds the index of the first value to satisfy the test callback.
     * If no value satisfies the test `-1` is returned.
     * @param callback Test callback
     * @returns number
     */
    findIndex(callback: ListTest<T>): number;
    /**
     * Find the first value to satisfy the test callback and returns it.
     * If no value satisfies the test `undefined` is returned.
     * @param callback Test callback
     * @returns Value or `undefined`
     */
    find(callback: ListTest<T>): T | undefined;
    /**
     * Returns `true` if a value exists in the List, `false` if not. Values
     * are compared with strict equality (`===`).
     * @param value Value to search
     * @returns boolean
     */
    includes(value: T): boolean;
    /**
     * Searches for value in the List and returns its index. If the value
     * is not found `-1` is returned. Values are compared with strict
     * equality (`===`).
     * @param value Value to search
     * @returns number
     */
    indexOf(value: T): number;
    /**
     * Runs a function on every element of the list. The function is passed the
     * current value, index, a reference to the full List and a reference to the
     * ListNode corresponding to the value. The return value of the callback is
     * ignored.
     * @param callback Function to run
     */
    forEach(callback: (value: T, index: number, self: List<T>, node: ListNode<T>) => void): void;
    /**
     * Creates a new list where each value is transformed by a callback
     * function. The function is passed the current value, index, a reference to
     * the full List and a reference to the ListNode corresponding to the value.
     * @param callback Callback to transform value
     * @returns new List
     */
    map<N>(callback: (value: T, index: number, self: List<T>, node: ListNode<T>) => N): List<N>;
    /**
     * Reduces a List to a single new value with a reducer function callback. The
     * callback is passed the current accumulated value, the next value taken from
     * the list, the index of that value, a reference to the full List and the
     * ListNode that corresponds to the value and index. The return value is used
     * as the new accumulated value or return from this method.
     * @param callback Reducer callback function
     * @param initialValue initial value to pass to the first iteration
     * @returns accumulated value
     */
    reduce<N>(callback: (accumulatedValue: N, value: T, index: number, self: List<T>, node: ListNode<T>) => N, initialValue: N): N;
    /**
     * Creates a copy of the current List in reverse order. The original List is
     * not modified.
     * @returns new List
     */
    reverse(): List<T>;
    /**
     * Creates a new List that contains a slice of value from the original List
     * starting at a given index up to an optional end index. If no end index is
     * given the rest of the List is included in the new List. Negative indexes
     * are handled the same as `Array.prototype.slice`. Values are copied to the
     * new List, meaning that modifying either List will not manipulate the other!
     * @param start Start index
     * @param end (optional) End index
     * @returns new List
     */
    slice(start: number, end?: number): List<T>;
    /**
     * Creates a new List with all values sorted by a comparison callback function.
     * The function should return a number value the first argument should appear
     * before the second argument, `0` if they're equal, or a positive number if
     * the first argument should appear after the second in the new List.
     * If no callback is passed values are sorted in ascending ASCII character order.
     * @param callback
     * @returns new sorted List
     */
    sort(callback?: (a: T, b: T) => number): List<T>;
    /**
     * Joins the List into a string, separating values with a configurable
     * separator string (`","` by default).
     * @param separator (optional) Custom separator string
     * @returns string
     */
    join(separator?: string): string;
    /**
     * Joins the List into a string using `","` as the separator. Use `join` if
     * you would like to use a different separator.
     * @returns
     */
    toString(): string;
    /**
     * Method for the Node.js Inspector
     * @param _ ignored depth parameter
     * @param options Options for the inspector to use on the list values (rendered as array)
     * @param inspect Please pass `node:util.inspect` here, thank you
     * @returns
     */
    [inspectSym](_: number, options: InspectOptions, inspect: InspectFn): string;
    [Symbol.iterator](): Generator<T, void, unknown>;
}
