Vue 3 中 inject 的类型安全需显式指定泛型或使用 Symbol + InjectionKey;推荐 InjectionKey 方式避免拼写错误并自动推导类型,配合封装 Hook 可提升复用性与健壮性。
在 Vue 3 的 Composition API 中使用
时,TypeScript 默认无法自动推断注入值的类型,因为
接收的是字符串 key,属于运行时信息。要获得完整的类型安全,需显式提供类型参数或利用依赖注入的类型声明机制。
手动指定泛型类型
最直接的方式是在调用
时传入泛型参数,明确告知 TypeScript 返回值类型:
写法示例:
若注入值可能为
(未提供 provider 或可选注入),应使用联合类型:
也可配合默认值避免
:
配合 provide 的类型定义统一管理
更健壮的做法是将注入的 key 和类型一起定义在模块中,形成“契约”:
创建一个
或
:
provide 侧使用该 symbol:
inject 侧直接使用,类型自动推导:
Symbol +
是 Vue 官方推荐方式,既保证类型安全,又避免字符串拼写错误
在 setup() 外部或组合式函数中安全使用
若在非 setup 函数(如工具函数、自定义 Hook)中调用
,需确保当前存在有效的 injection context:
Vue-router参考手册
Vue-router参考手册下载
下载
立即学习
“
前端免费学习笔记(深入)
”;
Vue 3 要求
必须在 setup()、生命周期钩子或已注册的组合式函数内调用;否则会返回
且无类型提示
建议封装带类型的注入函数,增强复用性:
这样调用方只需
,类型完全收敛在 Hook 内部
与 defineComponent / script setup 的协同
在
中,
的类型推断体验更自然:
配合
时,IDE 可直接跳转到类型定义,支持自动补全和错误检查
若使用字符串 key 且未标注泛型,TS 仅推导为
,失去类型保护 —— 应避免
Volar 插件对
中的
有额外优化,能结合
位置做轻量上下文分析(但不替代
)
injectinjectinjectconst store = inject('store'); undefinedconst api = inject('api'); undefinedconst config = inject('config', {} as Config); types.tsinjectionKeys.tsexport const StoreKey = Symbol('store') as InjectionKey; provide(StoreKey, store);const store = inject(StoreKey); // 类型即为 Store,无需泛型InjectionKeyinjectinjectundefinedexport function useStore() {
const store = inject(StoreKey);
if (!store) throw new Error('Missing store provider');
return store;
}const { state } = useStore();injectInjectionKeyanyinjectprovideInjectionKey