Dùng InjectionKey để provide/inject type-safe, tránh string key collisions:
typescript
// keys.ts — export typed keys
import type { InjectionKey, Ref } from 'vue'
export interface UserContext {
id: number
email: string
role: string
}
export const userContextKey: InjectionKey<UserContext> = Symbol('userContext')
export const themeKey: InjectionKey<Ref<'light' | 'dark'>> = Symbol('theme')
// Parent component
import { provide, ref } from 'vue'
import { userContextKey, themeKey } from './keys'
const theme = ref<'light' | 'dark'>('dark')
provide(themeKey, theme)
provide(userContextKey, { id: 1, email: 'user@test.com', role: 'admin' })
// Child component — fully typed
import { inject } from 'vue'
import { themeKey, userContextKey } from './keys'
const theme = inject(themeKey) // Ref<'light' | 'dark'> | undefined
const user = inject(userContextKey) // UserContext | undefined
// Với default value — loại bỏ undefined
const theme = inject(themeKey, ref('light')) // Ref<'light' | 'dark'>Dùng Symbol làm key thay vì string để tránh naming collision trong large apps hoặc libraries.