Using Provide/Inject with TypeScript

Show best practices for using provide/inject pattern in a TypeScript Vue3 application, ensuring type safety.
import { defineComponent, inject, provide, ref, Ref } from 'vue';

// Define the symbol key for the provided value
const MySymbol = Symbol();

interface MyData {
    value: string;

export default defineComponent({
    setup() {
        // Use ref to make it reactive
        const myValue: Ref<MyData> = ref({ value: 'This is provided data' });

        // Provide the reactive value to child components
        provide(MySymbol, myValue);

        return { myValue };
This code defines a Vue 3 component using TypeScript, sets up a reactive value with the 'ref' function, and provides it to all child components using the 'provide' function. A unique symbol 'MySymbol' is used as a key to prevent naming collisions.
import { defineComponent, inject } from 'vue';

// Import the symbol from its definition module
import { MySymbol } from './path-to-the-component-with-provide';

export default defineComponent({
    setup() {
        // Inject provided data using the same symbol key
        const myInjectedValue = inject(MySymbol);

        // TypeScript can't infer the type, so we cast it to the correct type
        if (!myInjectedValue) {
            throw new Error('myInjectedValue is not provided');

        // Use the injected value in your component
        return { myInjectedValue };
This piece of code shows a child component that uses 'inject' to receive data provided by its parent. The same 'MySymbol' is used to access the provided data. A check for undefined is necessary, as inject can return undefined if no value was provided under the key.