前言
创建 Vue3 + TypeScript + vueRouter 项目中,在计算属性中使用 route.name 获取当前页面名称时,tsc 验证出现 error TS2469 和 error TS2731
src/components/xx.vue(xx,xx): error TS2469: The '+' operator cannot be applied to type 'symbol'.
src/components/xx.vue(xx,xx): error TS2731: Implicit conversion of a 'symbol' to a 'string' will fail at runtime. Consider wrapping this expression in 'String(...)'.
网上查找发现当前(20220728)并无相关解决方案,经排查,判断错误由 TypeScript 执行类型检查时可能将 route.name 类型推断为 symbol 引起,查看解决方法可直接跳转至“解决方案”
错误情况
1.错误来源
在 Vue 组合式 SFC 编写中,使用 computed() 函数设置计算属性,并拼接为需要的字符串样式
<script setup lang="ts">
import { computed } from 'vue';
import { useRoute } from 'vue-router';
const route = useRoute();
// 计算属性
const routerName = computed<string>(() => {
return ' - ' + route.name + ' Page';
});
</script>
这种情况下,TypeScript 执行类型检查,会出现 error TS2469 错误
src/components/xx.vue(xx,xx): error TS2469: The '+' operator cannot be applied to type 'symbol'.
如果将计算属性 return 部分写作以下样式
return ` - ${ route.name } Page`;
TypeScript 执行类型检查,会出现 error TS2731 错误
src/components/xx.vue(xx,xx): error TS2731: Implicit conversion of a 'symbol' to a 'string' will fail at runtime. Consider wrapping this expression in 'String(...)'.
2.原因查找
使用 typeof() 函数读取 route.name 的类型,返回 string
console.log(typeof(route.name)); // 返回 string
使用 TypeScript Playground 查看错误情况和类型推断,结果如下
symbol 类型是 ES6 新增的一种基本数据类型,用于避免 JavaScript 第三方插件、框架所定义的属性或方法被覆盖
结合 error TS2469 和 error TS2731 错误提示,判断出错原因为 TypeScript 将 route.name 的类型判断为 symbol
而 symbol 类型是不能与其它字符串进行拼接的,故而引发此错误
解决方法
将被 TypeScript 推断为 symbol 类型的 route.name 转换为 string 类型即可
使用 JavaScript 的 String() 函数进行类型转换
return ' - ' + String(route.name) + ' Page'; // TypeScript 验证通过
或使用 TypeScript 的 as 关键字进行类型断言
return ` - ${ route.name as string } Page`; // TypeScript 验证通过