import type { AnyProcedure, inferProcedureInput, inferTransformedProcedureOutput } from './procedure';
import type { ProcedureCallOptions } from './procedureBuilder';
import type { AnyRootConfig } from './rootConfig';
import type { MaybePromise } from './types';
/** @internal **/
export type ProcedureRecord = Record<string, AnyProcedure>;
export interface ProcedureRouterRecord {
    [key: string]: AnyProcedure | AnyRouter;
}
export interface RouterDef<TConfig extends AnyRootConfig, TRecord extends ProcedureRouterRecord> {
    _config: TConfig;
    router: true;
    procedure?: never;
    procedures: TRecord;
    record: TRecord;
}
export type AnyRouterDef<TConfig extends AnyRootConfig = AnyRootConfig> = RouterDef<TConfig, any>;
type DecorateProcedure<TProcedure extends AnyProcedure> = (input: inferProcedureInput<TProcedure>) => Promise<TProcedure['_def']['_output_out']>;
/**
 * @internal
 */
type DecoratedProcedureRecord<TProcedures extends ProcedureRouterRecord> = {
    [TKey in keyof TProcedures]: TProcedures[TKey] extends AnyRouter ? DecoratedProcedureRecord<TProcedures[TKey]['_def']['record']> : TProcedures[TKey] extends AnyProcedure ? DecorateProcedure<TProcedures[TKey]> : never;
};
/**
 * @internal
 */
export type RouterCaller<TDef extends AnyRouterDef> = (
/**
 * @note
 * If passing a function, we recommend it's a cached function
 * e.g. wrapped in `React.cache` to avoid unnecessary computations
 */
ctx: TDef['_config']['$types']['ctx'] | (() => MaybePromise<TDef['_config']['$types']['ctx']>)) => DecoratedProcedureRecord<TDef['record']>;
export interface Router<TDef extends AnyRouterDef> {
    _def: TDef;
    /**
     * @deprecated use `t.createCallerFactory(router)` instead
     * @link https://trpc.io/docs/v11/server/server-side-calls
     */
    createCaller: RouterCaller<TDef>;
}
export type AnyRouter = Router<AnyRouterDef>;
type inferRouterDef<TRouter extends AnyRouter> = TRouter extends Router<infer TParams> ? TParams extends AnyRouterDef<any> ? TParams : never : never;
type inferRouterConfig<TRouter extends AnyRouter> = inferRouterDef<TRouter>['_config'];
export type inferRouterContext<TRouter extends AnyRouter> = inferRouterConfig<TRouter>['$types']['ctx'];
export type inferRouterError<TRouter extends AnyRouter> = inferRouterConfig<TRouter>['$types']['errorShape'];
export type inferRouterMeta<TRouter extends AnyRouter> = inferRouterConfig<TRouter>['$types']['meta'];
type GetInferenceHelpers<TType extends 'input' | 'output', TRouter extends AnyRouter> = {
    [TKey in keyof TRouter['_def']['record']]: TRouter['_def']['record'][TKey] extends infer TRouterOrProcedure ? TRouterOrProcedure extends AnyRouter ? GetInferenceHelpers<TType, TRouterOrProcedure> : TRouterOrProcedure extends AnyProcedure ? TType extends 'input' ? inferProcedureInput<TRouterOrProcedure> : inferTransformedProcedureOutput<TRouter['_def']['_config'], TRouterOrProcedure> : never : never;
};
export type inferRouterInputs<TRouter extends AnyRouter> = GetInferenceHelpers<'input', TRouter>;
export type inferRouterOutputs<TRouter extends AnyRouter> = GetInferenceHelpers<'output', TRouter>;
/**
 * @internal
 */
export type CreateRouterInner<TConfig extends AnyRootConfig, TProcRouterRecord extends ProcedureRouterRecord> = Router<RouterDef<TConfig, TProcRouterRecord>> & 
/**
 * This adds ability to call procedures directly but is primarily used for quick access in type inference
 */
TProcRouterRecord;
/**
 * @internal
 */
export declare function createRouterFactory<TConfig extends AnyRootConfig>(config: TConfig): <TProcRouterRecord extends ProcedureRouterRecord>(procedures: TProcRouterRecord) => CreateRouterInner<TConfig, TProcRouterRecord>;
/**
 * @internal
 */
export declare function callProcedure(opts: ProcedureCallOptions & {
    procedures: ProcedureRouterRecord;
}): Promise<unknown>;
export declare function createCallerFactory<TConfig extends AnyRootConfig>(): <TRouter extends Router<AnyRouterDef<TConfig>>>(router: TRouter) => RouterCaller<TRouter["_def"]>;
/** @internal */
type MergeRouters<TRouters extends AnyRouter[], TRouterDef extends AnyRouterDef = RouterDef<TRouters[0]['_def']['_config'], {}>> = TRouters extends [
    infer Head extends AnyRouter,
    ...infer Tail extends AnyRouter[]
] ? MergeRouters<Tail, {
    _config: TRouterDef['_config'];
    router: true;
    procedures: Head['_def']['procedures'] & TRouterDef['procedures'];
    record: Head['_def']['record'] & TRouterDef['record'];
}> : Router<TRouterDef> & TRouterDef['record'];
export declare function mergeRouters<TRouters extends AnyRouter[]>(...routerList: [...TRouters]): MergeRouters<TRouters>;
export {};
//# sourceMappingURL=router.d.ts.map