Bonjour,

Je souhaite connecter mon appli VueJS à une API, en faisant en sorte d'instancier qu'une seule fois la class qui gère l'API.
J'ai donc créé une class "Api" que j'instancie à la racine de l'application (fichier App.vue), puis je l'injecte dans mes sous-composants via la méthode "Provide / Inject".

L'objet est bien transféré à travers les couches de composants mais il perd son type lors du transfert, les proprités et les méthodes de l'objet sont donc inutilisables.

App.vue

<script lang="ts">

import Api from './api';

export default {
    provide: {
        api: new Api
    }
};

</script>

SubComponent.vue

<script lang="ts">

export default {
    inject: [
        'api'
    ],
    created() {

        console.log(this.api);

    }
}

</script>

Config

"vue": "^3.2.47",
"@vitejs/plugin-vue": "^4.1.0"
"typescript": "^5.0.2"
"vite": "^4.3.2",
"vue-tsc": "^1.4.2"

Ce que je veux

Que l'objet garde son type et ne devienne pas "unknown".

Ce que j'obtiens

L'application fonctionne quand même en mode "dev", mais le "build" plante avec l'erreur "error TS2571: Object is of type 'unknown'".

Je peux contourner le problème en créant une nouvelle variable à partir de l'objet que je caste avec le type "Api", mais j'aimerais pouvoir utiliser l'objet sans avoir à faire ces actions.

Avez-vous une idée de comment je pourrais procéder ?
Merci par avance,

Mickaël

2 réponses


Oh je ne connaissais pas provide / inject mais je suis tombé sur cet article qui semble donner la stratégie à adopter pour travailler avec TS : https://logaretm.com/blog/type-safe-provide-inject/

Merci pour ta réponse Grafikart !

Alors oui j'avais vu ce tuto. Ce qui m'inquiete c'est que tous les tutos que j'ai vu sur ce sujet utilisent la "Composition API", alors que moi j'utilise l' "Option API", je me demande si il n'y aurait pas une petite incompatibilité à ce niveau là... mais sans certitude, je n'ai pas tout réecris mon code pour vérifier si ça fonctionne mieux avec la "Composition API".

En revanche, ça fonctionne (build inclus) quand même si je caste l'élement injecté quand j'appel une propriété ou une fonction, voici ce que ça donne :

<script lang="ts">

import Api from './Api';

export default {
    inject: [
        'api'
    ],
    created() {

        // Api possede une propriété httpPath
        console.log( (this.api as Api).httpPath );

    }
}

</script>