import { CreatedRouteOptions, Route, RouteDataOf, Routes } from './route'; import { LastInArray } from './utilities'; import { ExtractRouteStateParamsAsOptional } from './state'; import { UrlString } from './urlString'; import { UrlParamsReading } from './url'; /** * The match a route resolved to, which is the last of its matches. Falls back to the wide match type when * the matches are not a concrete tuple, so an unregistered router stays assignable. */ type MatchedRoute = LastInArray extends infer TMatched ? unknown extends TMatched ? CreatedRouteOptions : TMatched : never; /** * Represents a route that the router has matched to current browser location. * @template TRoute - Underlying Route that has been resolved. */ export type ResolvedRoute = Readonly<{ /** * Unique identifier for the route, generated by router. */ id: TRoute['id']; /** * The specific route properties that were matched in the current route. */ matched: MatchedRoute; /** * The specific route properties that were matched in the current route, including any ancestors. * Order of routes will be from greatest ancestor to narrowest matched. */ matches: TRoute['matches']; /** * Unique identifier for the route. Name is used for routing and for matching. */ name: TRoute['name']; /** * Key value pair for route params, values will be the user provided value from current browser location. */ params: UrlParamsReading; /** * Type for additional data intended to be stored in history state. */ state: ExtractRouteStateParamsAsOptional; /** * String value of the resolved URL. */ href: UrlString; /** * Query value of the route. */ query: URLSearchParams; /** * Hash value of the route. */ hash: string; /** * Title of the route. */ title: Promise; }>; /** * A resolved route whose loaders' data is available. Only the route being navigated to has data: a route * the router merely resolved is not being loaded, so data on it could never settle. The current route and * a props getter's route have it, `router.resolve` and hooks do not. */ export type WithData = { /** * What the route's loaders resolve to, keyed by loader name. A route whose only loader is unnamed * exposes that loader's data here directly. Always promises, since loaders never block rendering. */ data: RouteDataOf; }; /** * This type is the same as `ResolvedRoute` while remaining distributive */ export type RouterResolvedRouteUnion = { [K in keyof TRoutes]: ResolvedRoute; }[number]; /** * Converts a union of Route types to a union of ResolvedRoute types while preserving the discriminated union structure for narrowing. * This is useful when you have a Route union (like `TRoutes[number]`) and need it to narrow properly. * Uses a distributive conditional type to ensure unions are properly distributed. * * @example * type RouteUnion = RouteA | RouteB * type ResolvedUnion = ResolvedRouteUnion // ResolvedRoute | ResolvedRoute */ export type ResolvedRouteUnion = TRoute extends Route ? ResolvedRoute : never; export {};