import type { ClientLoaderFunctionArgs, ClientActionFunctionArgs } from "./dom/ssr/routeModules";
import type { DataWithResponseInit } from "./router/utils";
import type { AppLoadContext } from "./server-runtime/data";
import type { Serializable } from "./server-runtime/single-fetch";
export type Expect<T extends true> = T;
type Equal<X, Y> = (<T>() => T extends X ? 1 : 2) extends (<T>() => T extends Y ? 1 : 2) ? true : false;
type IsAny<T> = 0 extends 1 & T ? true : false;
type IsDefined<T> = Equal<T, undefined> extends true ? false : true;
type Fn = (...args: any[]) => unknown;
type RouteModule = {
    loader?: Fn;
    clientLoader?: Fn;
    action?: Fn;
    clientAction?: Fn;
    HydrateFallback?: unknown;
    default?: unknown;
    ErrorBoundary?: unknown;
};
type VoidToUndefined<T> = Equal<T, void> extends true ? undefined : T;
type DataFrom<T> = IsAny<T> extends true ? undefined : T extends Fn ? VoidToUndefined<Awaited<ReturnType<T>>> : undefined;
type ClientData<T> = T extends DataWithResponseInit<infer U> ? U : T;
type ServerData<T> = T extends DataWithResponseInit<infer U> ? Serialize<U> : Serialize<T>;
type ServerDataFrom<T> = ServerData<DataFrom<T>>;
type ClientDataFrom<T> = ClientData<DataFrom<T>>;
type IsHydrate<ClientLoader> = ClientLoader extends {
    hydrate: true;
} ? true : ClientLoader extends {
    hydrate: false;
} ? false : false;
export type CreateLoaderData<T extends RouteModule> = _CreateLoaderData<ServerDataFrom<T["loader"]>, ClientDataFrom<T["clientLoader"]>, IsHydrate<T["clientLoader"]>, T extends {
    HydrateFallback: Fn;
} ? true : false>;
type _CreateLoaderData<ServerLoaderData, ClientLoaderData, ClientLoaderHydrate extends boolean, HasHydrateFallback> = [
    HasHydrateFallback,
    ClientLoaderHydrate
] extends [true, true] ? IsDefined<ClientLoaderData> extends true ? ClientLoaderData : undefined : [
    IsDefined<ClientLoaderData>,
    IsDefined<ServerLoaderData>
] extends [true, true] ? ServerLoaderData | ClientLoaderData : IsDefined<ClientLoaderData> extends true ? ClientLoaderData : IsDefined<ServerLoaderData> extends true ? ServerLoaderData : undefined;
export type CreateActionData<T extends RouteModule> = _CreateActionData<ServerDataFrom<T["action"]>, ClientDataFrom<T["clientAction"]>>;
type _CreateActionData<ServerActionData, ClientActionData> = Awaited<[
    IsDefined<ServerActionData>,
    IsDefined<ClientActionData>
] extends [true, true] ? ServerActionData | ClientActionData : IsDefined<ClientActionData> extends true ? ClientActionData : IsDefined<ServerActionData> extends true ? ServerActionData : undefined>;
type ClientDataFunctionArgs<Params> = {
    request: Request;
    params: Params;
};
type ServerDataFunctionArgs<Params> = ClientDataFunctionArgs<Params> & {
    context: AppLoadContext;
};
type Serialize<T> = T extends Serializable ? T : T extends (...args: any[]) => unknown ? undefined : T extends Promise<infer U> ? Promise<Serialize<U>> : T extends Map<infer K, infer V> ? Map<Serialize<K>, Serialize<V>> : T extends Set<infer U> ? Set<Serialize<U>> : T extends [] ? [] : T extends readonly [infer F, ...infer R] ? [Serialize<F>, ...Serialize<R>] : T extends Array<infer U> ? Array<Serialize<U>> : T extends readonly unknown[] ? readonly Serialize<T[number]>[] : T extends Record<any, any> ? {
    [K in keyof T]: Serialize<T[K]>;
} : undefined;
/**
 * @deprecated Generics on data APIs such as `useLoaderData`, `useActionData`,
 * `meta`, etc. are deprecated in favor of the `Route.*` types generated via
 * `react-router typegen`
 */
export type DeprecatedSerializeFrom<T> = T extends (...args: infer Args) => unknown ? Args extends [ClientLoaderFunctionArgs | ClientActionFunctionArgs] ? ClientData<DataFrom<T>> : ServerData<DataFrom<T>> : T;
export type CreateServerLoaderArgs<Params> = ServerDataFunctionArgs<Params>;
export type CreateClientLoaderArgs<Params, T extends RouteModule> = ClientDataFunctionArgs<Params> & {
    serverLoader: () => Promise<ServerDataFrom<T["loader"]>>;
};
export type CreateServerActionArgs<Params> = ServerDataFunctionArgs<Params>;
export type CreateClientActionArgs<Params, T extends RouteModule> = ClientDataFunctionArgs<Params> & {
    serverAction: () => Promise<ServerDataFrom<T["action"]>>;
};
export type CreateHydrateFallbackProps<Params> = {
    params: Params;
};
export type CreateComponentProps<Params, LoaderData, ActionData> = {
    params: Params;
    loaderData: LoaderData;
    actionData?: ActionData;
};
export type CreateErrorBoundaryProps<Params, LoaderData, ActionData> = {
    params: Params;
    error: unknown;
    loaderData?: LoaderData;
    actionData?: ActionData;
};
export {};
