/// <reference types="react" />
import { MetaDescriptor, Params, useFetcher, type FetcherWithComponents } from '@remix-run/react';
import type { MetaType } from './typedjson';
export type TypedJsonFunction = <Data extends unknown>(data: Data, init?: number | ResponseInit) => TypedJsonResponse<Data>;
export declare type TypedJsonResponse<T extends unknown = unknown> = Response & {
    typedjson(): Promise<T>;
    typeddefer(): Promise<T>;
};
export interface AppLoadContext {
    [key: string]: unknown;
}
type AppData = any;
type DataFunction = (...args: any[]) => unknown;
type DataOrFunction = AppData | DataFunction;
export interface DataFunctionArgs {
    request: Request;
    context: AppLoadContext;
    params: Params;
}
export type UseDataFunctionReturn<T extends DataOrFunction> = T extends (...args: any[]) => infer Output ? Awaited<Output> extends TypedJsonResponse<infer U> ? U : Awaited<ReturnType<T>> : Awaited<T>;
export declare const typedjson: TypedJsonFunction;
export declare const typeddefer: TypedJsonFunction;
export type TypedAwaitProps<T> = {
    resolve: Promise<T>;
    errorElement?: React.ReactNode;
    children: (data: T) => React.ReactNode;
};
export declare function TypedAwait<T>(props: TypedAwaitProps<T>): import("react/jsx-runtime").JSX.Element | null;
export declare function useTypedLoaderData<T = AppData>(): UseDataFunctionReturn<T>;
export declare function useTypedActionData<T = AppData>(): UseDataFunctionReturn<T> | null;
export type TypedFetcherWithComponents<T> = Omit<FetcherWithComponents<T>, 'data'> & {
    data: UseDataFunctionReturn<T>;
};
type FetcherArgs = Parameters<typeof useFetcher>[0];
export declare function useTypedFetcher<T>(opts?: FetcherArgs): TypedFetcherWithComponents<T>;
export declare function useTypedRouteLoaderData<T = AppData>(id: string): UseDataFunctionReturn<T> | undefined;
export type RemixSerializedType<T> = {
    $$obj: T | null;
    $$meta?: MetaType | null;
} & (T | {
    $$meta?: MetaType;
});
export declare function stringifyRemix<T>(data: T): string | null | undefined;
export declare function deserializeRemix<T>(data: RemixSerializedType<T>): T | null;
export type RedirectFunction = (url: string, init?: number | ResponseInit) => TypedJsonResponse<never>;
/**
 * A redirect response. Sets the status code and the `Location` header.
 * Defaults to "302 Found".
 *
 * @see https://remix.run/api/remix#redirect
 */
export declare const redirect: RedirectFunction;
export interface RouteData {
    [routeId: string]: AppData;
}
export interface LoaderFunction {
    (args: DataFunctionArgs): Promise<Response> | Response | Promise<AppData> | AppData;
}
/** @deprecated */
export interface TypedMetaFunction<Loader extends LoaderFunction | unknown = unknown, ParentsLoaders extends Record<string, LoaderFunction> = {}> {
    (args: {
        data: Loader extends LoaderFunction ? UseDataFunctionReturn<Loader> : AppData;
        parentsData: {
            [k in keyof ParentsLoaders]: UseDataFunctionReturn<ParentsLoaders[k]>;
        } & RouteData;
        params: Params;
        location: Location;
    }): MetaDescriptor;
}
export {};
