aurelia / router

A powerful client-side router.
MIT License
120 stars 115 forks source link

Typings for CanActivate and Activate seem slightly incomplete #688

Open m-gallesio opened 1 year ago

m-gallesio commented 1 year ago

I'm submitting a bug report

Current behavior: I am trying to use the RoutableComponent* interfaces, but the typings of canActivate and activate seem slightly incomplete.

export abstract class MyViewModel implements RoutableComponentCanActivate {
    async canActivate(routeParams: any, routeConfig: RouteConfig) {
        try {
            const redirect = this.getRedirect();
            if (redirect)
                return redirect;
            // ... other code          
            return true;
        }
        catch (err) {
            return false;
        }
    }
    // ... other code
}

This causes an error:

Error   TS2416  (TS) Property 'canActivate' in type 'MyViewModel' is not assignable to the same property in base type 'RoutableComponentCanActivate'.
  Type '(routeParams: any, routeConfig: RouteConfig) => Promise<boolean | NavigationCommand>' is not assignable to type '(params: any, routeConfig: RouteConfig, navigationInstruction: NavigationInstruction) => boolean | Promise<boolean> | PromiseLike<boolean> | NavigationCommand | Promise<...> | PromiseLike<...>'.
    Type 'Promise<boolean | NavigationCommand>' is not assignable to type 'boolean | Promise<boolean> | PromiseLike<boolean> | NavigationCommand | Promise<NavigationCommand> | PromiseLike<...>'.
      Type 'Promise<boolean | NavigationCommand>' is not assignable to type 'Promise<boolean>'.
        Type 'boolean | NavigationCommand' is not assignable to type 'boolean'.
          Type 'NavigationCommand' is not assignable to type 'boolean'. C:\DEV\HSE\src\Softcare.HSE.Web\tsconfig.json

Indeed, the type of the function is Promise<boolean | NavigationCommand> which is missing from the declaration.

Expected/desired behavior:

The page works correctly, so I think just adding Promise<boolean | NavigationCommand> (and possibly its analogous PromiseLike) would solve this problem. This would however bloat the return type, which can be solved by extracting an extra type definition like MaybePromiseOrPromiseLike<T>. Promise already satisfies PromiseLike, so it might be able to be skipped.