Angular使用枚举动态路由导航时类型报错问题及优化方案咨询
Angular使用枚举动态路由导航时类型报错问题及优化方案咨询
嘿,我来帮你拆解一下这个问题,顺便给你几个更顺手的写法参考!
首先说你为啥用枚举的时候不行——你定义的LinkType是默认的数字枚举,TS会给每个枚举成员自动分配数字值(比如LinkType.E_one的值是0,E_two是1),但你的LINKS对象的key是字符串'E_one'、'E_two'这种,用数字0去索引字符串key的对象,TS肯定不认啊!
要让枚举能正常用来索引,你得把它改成字符串枚举,让枚举成员的值和你要的key完全一致:
export enum LinkType { E_one = 'E_one', E_two = 'E_two', E_three = 'E_three' }
这样LinkType.E_one的值就是字符串'E_one',和LINKS的key对应上,这时候你再用as LinkType强制转换,TS就不会报错了:
this.router.navigate([LINKS[`E_${variable}` as LinkType]]);
不过说实话,枚举在这里有点“多此一举”的感觉,给你推荐两个更优雅的方案,不用手动维护枚举或者重复的联合类型:
方案一:自动推导key的联合类型
直接利用TS的keyof和typeof自动推导类型,以后新增路由链接时,只要改LINKS对象就行,类型会自动更新:
// 定义LINKS常量 export const LINKS = { E_one: '/url1/', E_two: '/url2/', E_three: '/url3/' } as const; // as const 确保TS推导最精确的类型,不会把值当成string // 自动提取LINKS的key作为联合类型 export type LinkKey = keyof typeof LINKS;
使用的时候:
this.router.navigate([LINKS[`E_${variable}` as LinkKey]]);
方案二:类型守卫+安全推导
如果你的variable是类似'one'、'two'这种后缀,还可以加个类型守卫,让TS自动推断合法性,不用强制转换:
// 定义合法的后缀数组 const validSuffixes = ['one', 'two', 'three'] as const; // 自动推导合法后缀的类型 type ValidSuffix = typeof validSuffixes[number]; // 类型守卫函数,判断输入是否为合法后缀 function isValidSuffix(s: string): s is ValidSuffix { return (validSuffixes as readonly string[]).includes(s); } // 使用时 if (isValidSuffix(variable)) { // 这里TS会自动知道`E_${variable}`是LINKS的合法key this.router.navigate([LINKS[`E_${variable}` as keyof typeof LINKS]]); } else { // 处理非法后缀的情况,比如导航到404或者默认页 this.router.navigate(['/not-found']); }
这种方式更安全,能避免因为variable值不合法导致的运行时错误。
总的来说,你之前的枚举问题就是没搞清楚数字枚举和字符串枚举的区别,改成字符串枚举就能用,但用自动推导类型的方案会更灵活省心。
内容来源于stack exchange
相关产品推荐
相关产品推荐

