Index

router-x/navigation/src/lib/types/composable-routes.types.ts

Properties

Properties

_RouteComposer_
_RouteComposer_: RouteComposer<Entity | FullPath | Name>
Type: RouteComposer<Entity | FullPath | Name>
import type { InjectionToken } from '@angular/core';
import type { Route } from '@angular/router';
import type { Join, NoTail } from '@bespunky/typescript-utils';
import type { _NavigatorXToken_, _RouteComposer_ } from '../_navigation-x.symbols';
import type { RouteComposer } from '../route-composer/router-composer';
import type { AutoNavigateRouteMethods } from './auto-navigator-methods.types';
import type { RouteComposerName } from './route-composer.types';
import type { CombinedPath, RouteSegments } from './route-paths.types';

export interface ReadonlyRoute<PathSegment extends string, FriendlyName extends string, Children extends DeepReadonlyRouteChildren | undefined> extends Readonly<Omit<Route, 'path' | 'children'>>
{
    /**
     * ### navigation-x property
     * 
     * Sets the contextual name for the route. This name will replace the method name automatically generated by `useNavigationX()`.
     * 
     * If you have a deep route, for example `theaters/:theaterId/shows/:showId`, the navigation method will automatically be named something like:
     * `toTheatersTheaterIdShowsShowId()`.
     * 
     * Specifying `friendlyName: 'ShowDetails'` for example, will make your navigation method receive the name `toShowDetails()`, which is nicer to read
     * and gives context as to where you're navigating to.
     *
     * @type {FriendlyName}
     */   
    readonly friendlyName?: FriendlyName;
    readonly path?: PathSegment;
    readonly children?: Children;
}

type MaxRouteChildrenDepth = 15;

export type DeepReadonlyRouteChildren<Depth extends number = MaxRouteChildrenDepth, Levels extends Array<boolean> = []> =
    readonly ReadonlyRoute<
        string,
        string,
        Levels[ 'length' ] extends Depth ? any : DeepReadonlyRouteChildren<Depth, [ ...Levels, true ]>
    >[];

export interface WithRouteComposer<Entity, FullPath extends string, Name extends string>
{
    readonly [ _RouteComposer_ ]: RouteComposer<Entity, FullPath, Name>;
}

export interface WithNavigationX<Route, Entity, Root extends string> {
    readonly [ _NavigatorXToken_ ]: InjectionToken<AutoNavigateRouteMethods<Route, Entity, Root>>;
};

export type ComposableRoutesArray<RouteArray, Entity, Root extends string> =
    RouteArray extends readonly [ infer First, ...infer Rest ] ?
    First extends ReadonlyRoute<infer Segment, string, any> ?
    readonly [
        ComposableRoute<First, Entity, CombinedPath<Root, Segment>>,
        ...ComposableRoutesArray<Rest, Entity, Root>
    ]
    : [] : [];

export type ComposableRoute<Route extends ReadonlyRoute<string, string, DeepReadonlyRouteChildren | undefined>, Entity, Root extends string> =
    Route extends ReadonlyRoute<infer Segment, infer FriendlyName, infer Children> ?
    & ReadonlyRoute<Segment, FriendlyName, Children>
    & WithRouteComposer<Entity, CombinedPath<Root, Segment>, RouteComposerName<FriendlyName, CombinedPath<Root, Segment>>>
    : never;

export type NavigationXRoute<ComposableR extends ComposableRoute<any, any, string>> =
    ComposableR extends ComposableRoute<infer Route, infer Entity, infer Root> ?
    & ComposableR
    & WithNavigationX<Route, Entity, Join<NoTail<RouteSegments<Root>> & string[], '/'>>
    : never;

results matching ""

    No results matching ""