Esse erro de erro de tipagem é porque você está utilizando TypeScript, e nos exemplos que te mandei eu estava com os componentes configurado para JavaScript. Sem os tipos.
Os mesmos exemplos, em TypeScript. A diferença é que precisamos fazer o setup usando a Composition API:
<template>
<h1>Componente avô com o método no provide</h1>
<ComponentePai />
</template>
<script lang="ts">
import { defineComponent } from "@vue/runtime-core";
import ComponentePai from "./ComponentePai.vue";
export default defineComponent({
components: { ComponentePai },
provide() {
return {
realizarAcao () {
console.log("Ação realizada no avô");
},
};
},
});
</script>
<template>
<h2>Componente Pai</h2>
<ComponenteFilho />
</template>
<script lang="ts">
import { defineComponent } from "@vue/runtime-core";
import ComponenteFilho from "./ComponenteFilho.vue";
export default defineComponent({
components: { ComponenteFilho },
});
</script>
<template>
<h3>Componente Filho</h3>
<button @click="aoClicado">Realizar açao</button>
</template>
<script lang="ts">
import { defineComponent, inject } from "@vue/runtime-core";
export default defineComponent({
inject: ["realizarAcao"],
setup () {
const realizarAcao = inject('realizarAcao') as () => void
return {
realizarAcao,
}
},
methods: {
aoClicado () {
console.log('método chamado no Filho')
this.realizarAcao()
}
}
});
</script>
Uma outra alternativa:
<template>
<h3>Componente Filho</h3>
<button @click="aoClicado">Realizar açao</button>
</template>
<script lang="ts">
import { defineComponent, inject } from "@vue/runtime-core";
export default defineComponent({
inject: ["realizarAcao"],
setup () {
const realizarAcao = inject<() => void>('realizarAcao')
return {
realizarAcao,
}
},
methods: {
aoClicado () {
console.log('método chamado no Filho')
if (this.realizarAcao) {
this.realizarAcao()
}
}
}
});
</script>
Depende de como você quer configurar a tipagem do seu provide/inject. Ainda existem outras formas, como por exemplo, criar interfaces ou tipos.