import { Component } from 'vue'; import { ComponentProps } from '../services/component'; import { ComponentPropsAreOptional, PropsGetter } from './createRouteOptions'; import { ResolvedRoute, WithData } from './resolved'; import { CreatedRouteOptions, Route } from './route'; import { RouteCallbackContext } from './routeCallbackContext'; import { RouteWithMethods } from './routeWithMethods'; import { PrefetchConfig } from './prefetch'; import { RouteView, RouteViews } from './routeViews'; import { Url } from './url'; import { AnyFunction, Identity, LastInArray, MaybePromise } from './utilities'; /** * The props getter for a view added via `addView`. Receives the same two arguments as the * `createRoute` props callback: the resolved route and a context object. */ export type AddViewPropsGetter = (route: ResolvedRoute & WithData, context: AddViewPropsCallbackContext) => MaybePromise>; /** * Context provided to an `addView` props getter. The same context a loader is given, since both are * callbacks attached to a route. */ export type AddViewPropsCallbackContext = RouteCallbackContext; /** * When the getter is omitted the default type param resolves to the wide getter type, which then * "extends" itself and collapses to undefined. When a getter is provided its return type is kept — the * view only needs what the props resolve to, not the signature it took to get there. */ type NewViewProps = AddViewPropsGetter extends TGetter ? undefined : ReturnType; /** * The options for a view added via `addView`. * * @template TName - The view's name, inferred from the `name` option. * @template TGetter - The view's props getter, inferred from the `props` option. */ export type AddViewOptions = { /** * The name of the view, rendered by ``. Defaults to the unnamed view. */ name?: TName; /** * A props getter for the view. Receives the resolved route and a context object. */ props?: TGetter; /** * Determines what assets are prefetched for this view when a router-link is rendered for this route. * Overrides route level prefetch, and is itself overridden by link level prefetch. */ prefetch?: PrefetchConfig; }; /** * {@link AddViewOptions} with `props` promoted to required. Only reached for components that have * required props — everything else uses {@link AddViewOptions}, where `props` stays optional, so a view * can always be given a name and a prefetch config without a getter. * * Spelled out rather than intersected with {@link AddViewOptions} so that the literal `name` still * infers through the conditional args tuple. */ type AddViewOptionsWithRequiredProps = { name?: TName; props: TGetter; prefetch?: PrefetchConfig; }; /** * The options argument for `addView`, required only when the component has required props. `TName` and * `TGetter` are inferred from the object's properties rather than from the object as a whole: inferring * the whole object as a `const` type param through this conditional tuple widens the literal name. */ type AddViewArgs = ComponentPropsAreOptional extends true ? [options?: AddViewOptions] : [options: AddViewOptionsWithRequiredProps]; /** * The views of the route itself, from the last `matches` entry. */ type CurrentMatchViews = LastInArray extends { views: infer TViews extends RouteViews; } ? TViews : RouteViews; /** * Computes the new views after adding a view, replacing any view already stored under the same name. */ export type AddViewProps = Identity> & Record, [TNewProps] extends [undefined] ? RouteView : RouteView>> extends infer TNext extends RouteViews ? TNext : TCurrent; type ViewName = TName extends string ? TName : 'default'; /** * Replaces the views on the last match, preserving all ancestors. */ type ReplaceLastMatchViews = TMatches extends [...infer THead extends CreatedRouteOptions[], infer TLast extends CreatedRouteOptions] ? Identity & { views: TNewViews; }> extends infer TNext extends CreatedRouteOptions ? [...THead, TNext] : TMatches : TMatches; /** * The full return type of an `addView` call: the same url with the last match's views replaced. */ type AddViewReturn = ReplaceLastMatchViews extends infer TNext extends CreatedRouteOptions[] ? RouteWithMethods : never; /** * Adds a view (component + optional props getter) to a route. Chainable to register multiple views, * including named views for named ``s. */ export type RouteAddView = { /** * Adds a view for this route. * * @param component - The component to render. Rendered by `` when the * options carry a name, and by the default `` otherwise. * @param options - The view's `name`, `props` getter, and `prefetch` config. Required when the * component has required props, optional otherwise. */ addView: , TComponent> = AddViewPropsGetter, TComponent>>(component: TComponent, ...options: AddViewArgs) => AddViewReturn, TName, NewViewProps, TComponent, TGetter>>>; }; export {};