如何在Vue单文件组件(SFC)中自定义$router类型覆盖默认声明
解决方案
你遇到的是TypeScript接口合并优先级的问题,vue-router官方包已经预先对Vue接口下的$router做了类型声明,默认你直接赋值的自定义类型会和官方声明做合并而不是覆盖,按以下步骤调整即可:
方案1:通过扩展VueRouter原生接口实现(推荐)
这是TS官方推荐的类型扩展方式,不会有优先级冲突,扩展的属性会自动合并到原有$router类型中:
// 在你的声明文件中新增如下代码,不需要修改原有Vue接口的$router定义 import type { VueRouter } from 'vue-router/types/router' declare module 'vue-router/types/router' { interface VueRouter { // 此处填写你自定义的属性、方法类型定义 // 示例: customNavigate: (path: string) => Promise<void> globalRouteMeta: Record<string, any> } }
修改后原有$router会自动包含你新增的属性类型,不需要再手动给Vue接口的$router赋值CustomRouter类型。
方案2:完全覆盖原有$router类型
如果你确实需要完全替换原有$router的类型,而非在原有基础上扩展,调整声明写法和TS配置即可:
- 调整声明文件内容:
import type { User } from '../common/api' import type { CustomRouter } from './router' declare module 'vue/types/vue' { interface Vue { $user: User // 这里单独声明$router,且加readonly修饰符提高优先级 readonly $router: CustomRouter } }
- 调整
tsconfig.json配置,让TS优先加载你项目的自定义声明:
{ "compilerOptions": { // 把你自定义声明文件所在的目录放在前面 "typeRoots": ["./src/typings", "./node_modules/@types"], }, // 确认include数组包含你的声明文件路径 "include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.vue"] }
生效验证
修改完成后,按Ctrl+Shift+P(Mac系统按Cmd+Shift+P),调出命令面板后选择「重启TypeScript服务器」,刷新后即可看到自定义$router类型生效。
内容的提问来源于stack exchange,提问作者Evan Summers
相关产品推荐
相关产品推荐

