@router-cli/react-router
Version:
File based routing cli for react-router-dom. Types and components. see @router-cli/react-router-dev for the cli and plugins.
135 lines (115 loc) • 5.22 kB
text/typescript
import { SetAction } from "./public/hooks";
import { ExtractSchema, ExtractRequiredSchema, ExtractRouteRequiredSchema, ExtractRouteSchema } from "./utils/types";
export type MergeTypeFromParent<TParent extends {}, TChild extends {}> = TParent & TChild;
export type RouteComponent<
TParams extends {} = {},
TSearchParams extends {} = {},
TLoader = unknown,
TParentRoute extends AnyRouteComponent = AnyRouteComponent,
>
= React.FC & {
routeData: RouteOptions<TParams, TSearchParams, TLoader, TParentRoute>
} & {
useParams(): keyof TParams extends never ? never : TParams;
useSearch(): keyof TSearchParams extends never ? never : [TSearchParams, (action: SetAction<TSearchParams>) => void];
childRoute<
TChildParams extends {} = {},
TChildSearchParams extends {} = {},
TChildLoader = unknown
>(content: React.FC, options?: Omit<RouteOptions<TChildParams, TChildSearchParams, TChildLoader, RouteComponent<TParams, TSearchParams, TLoader, TParentRoute>>, "__types" | "parent">): RouteComponent<MergeTypeFromParent<TChildParams, TParams>, MergeTypeFromParent<TChildSearchParams, TSearchParams>, TChildLoader>;
}
type LoaderArgs<
TParams extends {} | never = never,
TSearchParams extends {} | never = never,
> = {
pathname: string;
hash: string;
params: () => TParams;
search: () => TSearchParams;
}
type LoaderFunction<
TParams extends {} | never = never,
TSearchParams extends {} | never = never,
TResponse extends unknown = never,
> = (args: LoaderArgs<TParams, TSearchParams>) => Response | void | TResponse | Promise<Response | void | TResponse>;
export interface RouteOptions<
TParams extends {} | never = never,
TSearchParams extends {} | never = never,
TLoader extends unknown = never,
TParentRoute extends AnyRouteComponent = AnyRouteComponent,
> {
Error?: React.FC;
Pending?: React.FC;
useGuards?: () => boolean | void | null | undefined;
paramsSchema?: ParamSchema<TParams>;
searchSchema?: ParamSchema<TSearchParams>;
loader?: LoaderFunction<TParams, TSearchParams, TLoader>;
parentRoute?: TParentRoute,
disableDefaultPendingComponent?: boolean,
disableDefaultErrorComponent?: boolean,
"__types": {
params: TParams,
search: TSearchParams;
loader: TLoader;
parent: TParentRoute;
}
};
export type AppRoutes = {
app: React.ComponentType<any> | undefined;
notFound: React.ComponentType<any> | undefined;
error: React.ComponentType<any> | undefined;
pending: React.ComponentType<any> | undefined;
};
export type AnyRouteComponent = RouteComponent<any, any, any, any>;
export type AnyRouteOptions = RouteOptions<any, any, any, any>;
export type TypedPath<TPath extends string> = { to: TPath; hash?: string; };
export type TypedParamsSchema<T extends AnyRouteOptions, TSchema extends keyof T["__types"], TTypes extends RouteSchemaTypes<T, TSchema> = RouteSchemaTypes<T, TSchema>> =
TTypes["hasRequiredFields"] extends true
? { [key in TSchema]: TTypes["source"]; }
: TTypes["hasAnyFields"] extends true
? { [key in TSchema]?: TTypes["source"]; }
: {}
export type TypedSearchParams<TRoute extends AnyRouteOptions> = TRoute extends RouteOptions<any, {}, any> ? { search: TRoute["__types"]["search"]; } : { search?: TRoute["__types"]["search"] };
export type TypedTo<
TPath extends string,
TRoute extends AnyRouteComponent,
>
= TypedPath<TPath>
& TypedParamsSchema<TRoute["routeData"], "search">
& TypedParamsSchema<TRoute["routeData"], "params">
export type TypedToOrPath<
TPath extends string,
TRoute extends AnyRouteComponent,
>
= ExtractRouteRequiredSchema<TRoute["routeData"], "search"> extends false
? ExtractRouteRequiredSchema<TRoute["routeData"], "params"> extends false
? TPath | TypedTo<TPath, TRoute>
: TypedTo<TPath, TRoute>
: TypedTo<TPath, TRoute>;
export type ParamSchema<TReturn> =
| ParamSchemaObj<TReturn>
| ParamSchemaFn<TReturn>
export type ParamSchemaObj<TReturn> = {
parse?: ParamSchemaFn<TReturn>
}
export type ParamSchemaFn<TReturn> = (
obj: Record<string, unknown>,
) => TReturn
export type RouteSchemaTypes<T extends AnyRouteOptions, TSchema extends keyof T["__types"]> = {
hasAnyFields: ExtractRouteSchema<T, TSchema> extends never ? false : true;
hasRequiredFields: ExtractRouteRequiredSchema<T, TSchema> extends never ? false : true;
source: T["__types"][TSchema];
}
export type SchemaTypes<T extends {} | never> = {
hasAnyFields: ExtractSchema<T> extends never ? false : true;
hasRequiredFields: ExtractRequiredSchema<T> extends never ? false : true;
source: T;
}
export type AnyRouteImport = () => Promise<AnyRouteComponent>;
export type AnyRouteImports = Record<string, () => Promise<AnyRouteComponent>>;
export type AnyRouteComponents = Record<string, AnyRouteComponent>;
export interface AnyRouter {
pages: AnyRouteImports;
layouts: AnyRouteImports;
app: AppRoutes;
}