I want to make the routes passed to the Angular Router a constant so that I can have IntelliSense for all possible route paths:
const route = [
{ path: 'my-path', component: MenuItemsComponent },
{ path: 'my-path', component: MenuItemsComponent },
] as const;
const myRoutes = route as Routes;
Typescript says I can't do this, it throws this error:
Conversion of type 'readonly [{ readonly path: "my-path"; readonly component: typeof MenuItemsComponent; }, { readonly path: "my-path"; readonly component: typeof MenuItemsComponent; }]' to type 'Routes' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first.
The type 'readonly [{ readonly path: "my-path"; readonly component: typeof MenuItemsComponent; }, { readonly path: "my-path"; readonly component: typeof MenuItemsComponent; }]' is 'readonly' and cannot be assigned to the mutable type 'Routes'.
But why is Routes a mutable type? I can't understand.
To explain why i need const, is because in with consts we can do that:
type Path = typeof route[number]['path'];
So now i can restrict a variable to a path declared in the router.
I did a quick test on my local and your code compiles fine with Angular 11.
If your real concern is auto complete in your IDE; then you can try a conversion, like this:
const route: routes = [
{ path: 'my-path', component: MenuItemsComponent } as Route,
{ path: 'my-path', component: MenuItemsComponent } as Route,
] as const;
And I get AutoComplete in IntelliJ:

An alternate option might be to create your own class that extends the Route interface and use that to create your own Route interfaces.
Generally like this:
export class MyRouteClass extends Route {
path?: string
pathMatch?: string
matcher?: UrlMatcher
component?: Type<any>
redirectTo?: string
outlet?: string
canActivate?: any[]
canActivateChild?: any[]
canDeactivate?: any[]
canLoad?: any[]
data?: Data
resolve?: ResolveData
children?: Routes
loadChildren?: LoadChildren
runGuardsAndResolvers?: RunGuardsAndResolvers
}
and then:
const route: routes = [
Object.assign(new MyRouteClass(), { path: 'my-path', component: MenuItemsComponent }),
Object.assign(new MyRouteClass(), { path: 'my-path', component: MenuItemsComponent }),
];
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With