Search code examples
javascriptangulartypescriptangular-router

Angular 7.2.0: Type 'string' is not assignable to type 'RunGuardsAndResolvers'


Angular compiler-cli v.7.2.0 is throwing:

Types of property 'runGuardsAndResolvers' are incompatible. Type 'string' is not assignable to type 'RunGuardsAndResolvers'

when setting runGuardsAndResolvers: 'always' in a constant which is imported into AppRoutingModule.

This does not occur when I set runGuardsAndResolvers: 'always' within AppRoutingModule itself.

app-routing.module.ts

import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { adminRouterConfig } from 'src/app/core/_routing/admin-router-config';

const appRoutes: Routes = [
  { path: '', component: HomeComponent },
  {
    path: '',
    children: [
      ...adminRouterConfig
    ]
  },
  { path: '**', redirectTo: '', pathMatch: 'full' }
  ];

@NgModule({
  imports: [RouterModule.forRoot(appRoutes,
                                 { enableTracing: true }
)],
  exports: [RouterModule]
})

export class AppRoutingModule { }

admin-router-config.ts

import { AuthGuard } from 'src/app/core/_guards/auth.guard';

export const adminRouterConfig = [
  {
    path: 'admin',
    runGuardsAndResolvers: 'always',
    canActivate: [AuthGuard],
    children: [
      ...
    ]
  }
];

Solution

  • This is just the way type inference works in TypeScript. When you first assign it to a variable, it will infer the type for the variable to {runGuardsAndResolvers: string} and then it doesn't match when it is used later. In this case, you have to specify the type explicitly:

    const options = {
      runGuardsAndResolvers: "always" as RunGuardsAndResolvers
    };
    

    Have a look at this example:

    const method = (options: { runGuardsAndResolvers: RunGuardsAndResolvers }) => {
      return options;
    };
    
    // This works
    method({ runGuardsAndResolvers: "always" });
    
    // This fails
    const options = { runGuardsAndResolvers: "always" };
    method(options);
    
    // This works
    const typedOptions = {
      runGuardsAndResolvers: "always" as RunGuardsAndResolvers
    };
    method(typedOptions);
    

    Live demo:

    Edit Typescript type inference