RFC: deprecate defineRouteMeta function in favor of RouteMeta type/interface

This issue has been tracked since 2023-01-16.

Which scope/s are relevant/related to the feature request?

router

Information

The defineRouteMeta function causes issues when eagerly loading files using glob imports with Vite. The function is only used to enforce the type for restricting what can be provided as route metadata.

Proposed

Before:

// src/app/routes/index.ts
import { defineRouteMeta } from '@analogjs/router';

export const routeMeta = defineRouteMeta({
  title: 'Home',
});

After:

// src/app/routes/index.ts
import { RouteMeta } from '@analogjs/router';

export const routeMeta: RouteMeta = {
  title: 'Home',
};

Describe any alternatives/workarounds you're currently using

No response

I would be willing to submit a PR to fix this issue

  • Yes
  • No
markostanimirovic wrote this answer on 2023-01-18

Thoughts on defining RouteMeta type like this?

Differences compared to the original Angular Route interface:

  • Removed deprecated canLoad property.
  • Guards and resolvers are strongly typed (when using Route interface we can pass any[]).
  • Class-based guards and resolvers are not supported because they're deprecated in Angular Route.
  • Used exclusive union for the possible route property combinations. This will throw a compilation error if a forbidden combination of route properties is used. Unlike Angular `Route', where compilation will pass and a runtime error will be thrown in this case.
brandonroberts wrote this answer on 2023-01-18

Looks reasonable to be. Should we not extend/override the Angular Route instead of recreating the route type for DefaultRouteMeta?

markostanimirovic wrote this answer on 2023-01-18

Looks reasonable to be. Should we not extend/override the Angular Route instead of recreating the route type for DefaultRouteMeta?

@brandonroberts We can define DefaultRouteMeta like this and override only weakly typed route props:

type OmittedRouteProps =
  | 'path'
  | 'pathMatch'
  | 'matcher'
  | 'redirectTo'
  | 'component'
  | 'loadComponent'
  | 'children'
  | 'loadChildren'
  | 'canLoad'
  | 'outlet';

interface DefaultRouteMeta extends Omit<Route, OmittedRouteProps> {
  canActivate?: CanActivateFn[];
  canActivateChild?: CanActivateChildFn[];
  canDeactivate?: CanDeactivateFn<unknown>[];
  canMatch?: CanMatchFn[];
  resolve?: { [key: string | symbol]: ResolveFn<unknown> };
  title?: string | ResolveFn<string>;
}

interface RedirectRouteMeta {
  redirectTo: string;
  pathMatch?: Route['pathMatch'];
}

export type RouteMeta =
  // enforce exclusive union
  | (DefaultRouteMeta & { redirectTo?: never })
  | RedirectRouteMeta;
brandonroberts wrote this answer on 2023-01-18

👍

More Details About Repo
Owner Name analogjs
Repo Name analog
Full Name analogjs/analog
Language TypeScript
Created Date 2022-07-06
Updated Date 2023-03-28
Star Count 885
Watcher Count 18
Fork Count 67
Issue Count 33

YOU MAY BE INTERESTED

Issue Title Created Date Updated Date