declare global {
    namespace Api {
        namespace Mocker {
            /**
             * Классический трюк: заставляет TS раскрыть алиас в структурный тип, тем самым устраняя разницу между «инлайн» и «через имя типа».
             */
            type Expand<T> = T extends infer U ? {
                [K in keyof U]: U[K];
            } : never;
            /**
             * Настройки генерации результата
             *
             * Объект, массив или просто значение
             *
             * Для генерации можно использовать библиотеку **faker-js**
             *
             * Пример:
             *
             * ```
             * [{
             *  id: faker.number.int,
             *  name: faker.name.firstName,
             *  email: faker.internet.email,
             * }]
             * ```
             *
             * @see https://fakerjs.dev/
             */
            type Result = [Item] | Item | Value;
            /**
             * Генератор элемента результата
             *
             * Пример:
             *
             * ```
             * {
             *  id: faker.number.int,
             *  name: faker.name.firstName,
             *  email: faker.internet.email,
             * }
             */
            type Item = Record<string, Value>;
            /**
             * Генератор значения
             *
             * Пример:
             *
             * ```
             * faker.number.int
             * ```
             */
            type Value = (n: number, fields?: readonly string[], params?: Api.Mocker.Params) => any;
            type Params = Record<string, any>;
            type Options<Result extends Api.Mocker.Result, Params extends Api.Mocker.Params> = {
                /**
                 * Шаблон генерации результата
                 *
                 * Если результат массив, то будут учтены параметры: `fields`, `limit` и настройка `useFilter()`
                 *
                 * Если результат объект, то будет учтен параметр: `fields`
                 */
                result: Result;
                /**
                 * Если указано, будет подключен механизм пагинации с `total` и `nextOffset`
                 *
                 * Только если `result` массив
                 */
                total?: number;
                /**
                 * Функция для фильтра сгенерированных моков
                 *
                 * Для имитации работы фильтров в методах API
                 *
                 * Только если `result` массив
                 *
                 * @return Вернет `true`, если сгенерированный мок должен попасть в результат
                 */
                useFilter?: (resultItem: Result extends [Item] ? ToMockItem<Result[0]> : Result extends Value ? ReturnType<Result>[number] : never, params: Params) => boolean;
                /**
                 * Пауза перед возвращением результата
                 *
                 * @see https://fakerjs.dev/api/simpleFaker.html#delay
                 */
                delay?: number;
                /**
                 * Показывать ли лог мокирования запросов
                 */
                showLog?: boolean;
                /**
                 * Начальное значение рандомайзера
                 *
                 * Установите `-1`, если хотите, чтобы данные менялись каждый запрос, `-1` нельзя использовать в кейсах с фильтрацией, сортировкой и пагинацией
                 *
                 * @see https://fakerjs.dev/api/simpleFaker.html#seed
                 */
                seed?: number;
            };
            type ToMockItem<T extends Item> = {
                [K in keyof T]: ReturnType<T[K]>;
            };
            type ToMockValue<T extends Value> = ReturnType<T>;
            type ToMockResult<T extends Result> = T extends [infer I extends Item] ? ToMockItem<I>[] : T extends Item ? ToMockItem<T> : T extends Value ? ToMockValue<T> : never;
        }
    }
}
export {};
