import { TailParams } from "./type";
export declare type Gen<T = any> = Generator<RecursiveYield | undefined, T, RecursiveNext>;
export declare type AGen<T = any> = AsyncGenerator<RecursiveYield | undefined, T, RecursiveNext>;
export declare type GenRet<T extends Gen | AGen> = T extends Gen<infer R> ? R : T extends AGen<infer R> ? R : never;
export declare type GenFnRet<F extends ((...a: any[]) => Gen) | ((...a: any[]) => AGen)> = GenRet<ReturnType<F>>;
export declare type RecursiveYield<T = any> = () => Gen<T>;
export declare type ARecursiveYield<T = any> = () => AGen<T>;
export declare type RecursiveNext<T = any> = T;
export declare class RecursiveCtx {
    get<F extends (ctx: RecursiveCtx, ...args: any[]) => Gen>(_: F, result: RecursiveNext<GenFnRet<F>>): GenFnRet<F>;
    call<F extends (ctx: RecursiveCtx, ...args: any[]) => Gen>(fn: F, ...args: TailParams<F>): RecursiveYield<GenFnRet<F>>;
}
declare type MayA = ((ctx: RecursiveCtx, ...args: any[]) => Gen) | ((ctx: RecursiveCtx, ...args: any[]) => AGen) | ((ctx: AsyncRecursiveCtx, ...args: any[]) => Gen) | ((ctx: AsyncRecursiveCtx, ...args: any[]) => AGen);
declare class AsyncRecursiveCtx {
    get<F extends MayA>(_: F, result: RecursiveNext<GenFnRet<F>>): GenFnRet<F>;
    call<F extends MayA>(fn: F, ...args: TailParams<F>): RecursiveYield<GenFnRet<F>> | ARecursiveYield<GenFnRet<F>>;
}
declare const _AsyncRecursiveCtx: typeof AsyncRecursiveCtx;
export { _AsyncRecursiveCtx as AsyncRecursiveCtx };
export declare function doRecursive<F extends (ctx: RecursiveCtx, ...args: any[]) => Gen>(fn: F, ...args: TailParams<F>): GenFnRet<F>;
export declare function doRecursiveAsync<F extends MayA>(fn: F, ...args: TailParams<F>): Promise<GenFnRet<F>>;
