You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Aurelia+TypeScript导航授权问题:代码执行异常与类型提示报错

解决Aurelia导航守卫的两个问题:代码中断与TypeScript类型错误

嘿,看来你碰到了两个关联的问题:TypeScript的类型提示错误引发了运行时异常,直接导致TEST2的代码根本没机会执行。咱们一步步来拆解解决:

1. 先搞定TypeScript的类型提示错误

这个Parameter 'r' implicitly has an 'any' type错误,本质是TS没法推断出r的具体类型——因为你路由配置里的settings.roles没有明确的类型声明。咱们给它补上类型定义就行:

第一步:定义角色的类型

先给角色明确一个类型,用字符串字面量或者枚举都可以,根据你的业务场景选:

// 方案1:字符串字面量类型,限定只能是指定的角色值
type Role = 'admin' | 'regular_user' | 'guest';

// 方案2:枚举类型,更适合有大量角色或者需要统一管理的场景
enum Role {
  Admin = 'admin',
  RegularUser = 'regular_user',
  Guest = 'guest'
}

第二步:扩展Aurelia的路由配置类型

让TS知道咱们的路由配置里settings可以包含roles属性,直接扩展框架自带的RouteConfig就行:

import { RouteConfig } from 'aurelia-router';

interface ExtendedRouteConfig extends RouteConfig {
  settings?: {
    roles?: Role[]; // 明确roles是Role类型的数组
  };
}

第三步:修正导航守卫里的类型断言

在获取requiredRoles的时候,给路由配置加上类型断言,让TS识别出它是咱们扩展后的类型,同时加个兜底避免undefined:

let requiredRoles = (navigationInstruction.getAllInstructions()
  .map(i => (i.config as ExtendedRouteConfig).settings?.roles) || [])[0];

这里用|| []是防止某个路由的settings.roles没配置时,后续调用some方法报错。

2. 解决TEST2代码未执行的问题

TEST2没执行的核心原因是:计算isUserInRole的时候抛出了异常,导致代码直接中断。上面的类型修正已经解决了最可能的异常源,再加上一些防御性代码更稳妥:

检查用户角色的有效性

先确保this.userIdentity和它的role属性不是undefined,避免空值比较引发错误:

const userRole = this.userIdentity?.role;
let isUserInRole = true;

// 只有当需要的角色和用户角色都存在时,才做权限校验
if (requiredRoles && userRole) {
  isUserInRole = requiredRoles.some(r => r === userRole);
} else if (requiredRoles) {
  // 有要求的角色,但用户没有角色,直接判定无权限
  isUserInRole = false;
}

完整修正后的代码

把所有改动整合起来,最终的导航守卫代码是这样的:

import { NavigationInstruction, Next, Redirect, RouteConfig } from 'aurelia-router';
import toastr from 'toastr';

// 定义角色类型,根据你的实际业务调整
type Role = 'admin' | 'regular_user' | 'guest';

// 扩展路由配置类型
interface ExtendedRouteConfig extends RouteConfig {
  settings?: {
    roles?: Role[];
  };
}

export class AuthGuard {
  // 这里根据你的实际userIdentity结构调整类型
  private userIdentity: { role?: Role };

  run(navigationInstruction: NavigationInstruction, next: Next): Promise<any> { 
    let requiredRoles = (navigationInstruction.getAllInstructions()
      .map(i => (i.config as ExtendedRouteConfig).settings?.roles) || [])[0]; 

    toastr.success('TEST1'); 

    const userRole = this.userIdentity?.role;
    let isUserInRole = true;

    if (requiredRoles && userRole) {
      isUserInRole = requiredRoles.some(r => r === userRole);
    } else if (requiredRoles) {
      isUserInRole = false;
    }

    toastr.success('TEST2'); // 现在应该能正常执行了
    return isUserInRole ? next() : next.cancel(new Redirect('users/login')); 
  }
}

额外排查点(如果还是不行的话)

要是修正后TEST2依然没执行,建议加几个日志排查:

  • toastr.success('TEST1')后面加console.log('requiredRoles:', requiredRoles),确认它是不是你预期的数组格式。
  • console.log('userIdentity:', this.userIdentity),看看this.userIdentity有没有值,role属性是不是存在。

内容的提问来源于stack exchange,提问作者4est

火山引擎 最新活动