5 votes

Les déclarations émises par Typescript ne trouvent pas le nom de l'interface globale

Ce problème se pose dans une bibliothèque CDN privée. Je veux générer des fichiers de déclaration TypeScript pour le développement d'applications qui intègrent la bibliothèque. Le problème est que les fichiers de déclaration générés présentent des erreurs "cannot find name" concernant les interfaces globales correctement définies.

Tout d'abord, les options du compilateur de la bibliothèque CDN ont emitDeclarationOnly y declaration vrai. Cela place correctement les déclarations dans le répertoire "types".

 "compilerOptions": {
    "module": "es2020",
    "target": "es2020",
    "sourceMap": true,
    "checkJs": true,
    "allowJs": true,
    "emitDeclarationOnly": true,
    "declaration": true,
    "outDir": "types"

    // .... paths etc. omitted
  }

Deuxièmement, j'ai un fichier de déclaration d'interface globale qui déclare environ 7 ou 8 interfaces différentes.

// global.ts
    interface ComponentToggle {
        component: HTMLElement,

        // other properties here
    }

    // more interfaces here

Troisièmement, les fichiers sources JavaScript originaux peuvent utiliser les interfaces globales dans les JSDocs. Ces fichiers utilisent les JSDocs pour définir leurs informations TypeScript. Ils sont compilés en .d.ts sans aucune erreur.

// otherfile.js
    /** Removes active state from all options.
     *
     * @param toggle {ComponentToggle} the parent element toggle message
     */
    inactivate( { component } ) {
        if ( component.contains( this ) ) {
            this.getOptions( true ).forEach( option => option.inactivate() );
        }
    }

Les fichiers d.ts générés sont tous corrects.

// global.d.ts
    interface ComponentToggle {
        component: HTMLElement,

        // identical to the ts file
    }

// otherfile.d.ts
    /** Removes active state from all options.
     *
     * @param toggle {ComponentToggle} the parent element toggle message
     */
    inactivate({ component }: ComponentToggle): void;

Maintenant, nous arrivons au problème. Lorsque l'on essaie d'utiliser otherfile.d.ts il y a une nouvelle erreur TypeScript :

TS2304: Cannot find name 'ComponentToggle'.

Quelqu'un peut-il expliquer ce qui se passe ? Comment se fait-il que l'interface globale ComponentToggle ne peut être trouvé ici alors qu'il a été littéralement juste utilisé pour générer ce fichier ?

EDIT : Principalement, je remarque qu'il y a un problème dès que j'ouvre les fichiers d.ts concernés, car l'analyseur WebStorm les signale.

Comme demandé, voici la tsconfig de l'application que j'utilise pour tester ceci, qui n'est pas non plus une application TypeScript. Je ne suis propriétaire d'aucune des applications qui utiliseront cette bibliothèque. Comme il s'agit d'une utilisation CDN, la bibliothèque est définie dans le code source en utilisant des chemins locaux commençant par /xxxyyy/ (voir ci-dessous) qui sont définis comme "externes" dans Webpack et également comme chemins proxy dans Karma. La compilation (moins tsc ) et les tests unitaires fonctionnent bien, et les types de la bibliothèque sont correctement trouvés. WebStorm affiche correctement les types et les conseils pour les fichiers qui n'ont pas ce problème, et l'exécution de la commande tsc produit exactement les mêmes erreurs que WebStorm affiche lorsque j'ouvre les fichiers.

L'application de consommation :

{
  "include": [
    "src/**/*"
  ],
  "exclude": [
    "node_modules",
    "ci-output",
    "unitTest",
    "tutorials",
    "lib"
  ],
  "compilerOptions": {
    "module": "es2020",
    "target": "es2020",
    "sourceMap": true,
    "checkJs": true,
    "allowJs": true,
    "emitDeclarationOnly": true,
    "declaration": true,
    "outDir": "types",
    "downlevelIteration": true,
    "baseUrl": ".",
    "paths": {
      "*": [ "AppMain", "./src/component/app-main.js" ],
      "/xxxyyy/libraryname.min.js": [ "libraryname", "./node_modules/@xxxyyy/libraryname/types/index.d.ts" ],
      "/xxxyyy/libraryname.js": [ "libraryname", "./node_modules/@xxxyyy/libraryname/types/index.d.ts" ]
    }
  }
}

La bibliothèque elle-même :

{
  "include": [
    "src/**/*"
  ],
  "exclude": [
    "node_modules",
    "ci-output",
    "conf",
    "jsdocTemplate",
    "unitTest",
    "tutorials"
  ],
  "compilerOptions": {
    "module": "es2020",
    "target": "es2020",
    "sourceMap": true,
    "checkJs": true,
    "allowJs": true,
    "emitDeclarationOnly": true,
    "declaration": true,
    "outDir": "types",
    "baseUrl": "./",
    "paths": {
      "*": [ "MainComponent", "./src/component/MainComponent.js" ]
    }
  }
}

EDIT 2 Bon, puisque personne ne semble avoir de réponse pour moi, je vais essayer une autre approche. Chacun de ces globaux correspond à l'une des catégories suivantes :

  1. Un "polyfill" parce que les définitions intégrées de Window de TypeScript manquent de certaines choses.
  1. Définitions de ce que certaines fonctions s'attendent à recevoir comme paramètres d'objets.
  • Dans l'exemple ci-dessus, j'ai défini ComponentToggle parce qu'il existe de nombreuses fonctions qui prennent un seul objet comme paramètre, et cet objet a un ensemble spécifique de propriétés qui seront déstructurées. Je veux définir ces propriétés pour que l'application consommatrice sache comment appeler les fonctions.

Est-ce qu'il y a tout ce que je peux faire pour répondre aux exigences #1 et #2 qui n'implique pas la création d'un fichier global.ts ?

Sinon, comment faire pour que le fichier global.d.ts généré soit consommé par WebStorm et l'application ? Dois-je définir des configurations dans "paths", "types", "typeRoots", ou autre chose dont je n'ai pas encore entendu parler ?

De plus, les commentaires sur cette question semblent supposer que je sais des choses. Je ne connais rien du tout à TypeScript. Je pourrais très bien faire la plus débutante des erreurs ici.

0voto

miyasudokoro Points 1632

J'espère que quelqu'un a une meilleure réponse que celle-ci. Je n'aime pas vraiment cette solution, car elle oblige l'application de consommation à placer les informations sur ma bibliothèque à deux endroits différents dans sa base de données. tsconfig .

J'ai creusé dans un millier d'endroits. Finalement, j'ai trouvé quelque chose à propos des directives triple slash. Quand je mets manuellement une directive triple slash /// <reference path="./global.d.ts" en haut du fichier index.d.ts, tout a commencé à fonctionner comme par magie. J'ai ensuite fait des recherches pour savoir comment tsconfig avait remplacé les directives à triple slash. Voici la réponse que je cherchais :

L'application de consommation :

{
  "include": [
    "src/**/*",
    "node_modules/@xxxyyy/libraryname/types/global.d.ts"
  ],
  "exclude": [
    // I had to remove "node_modules" from this list
    "ci-output",
    "unitTest",
    "tutorials",
    "lib"
  ],
  "compilerOptions": {
    "module": "es2020",
    "target": "es2020",
    "sourceMap": true,
    "checkJs": true,
    "allowJs": true,
    "emitDeclarationOnly": true,
    "declaration": true,
    "outDir": "types",
    "downlevelIteration": true,
    "baseUrl": ".",
    "paths": {
      "*": [ "AppMain", "./src/component/app-main.js" ],
      "/xxxyyy/libraryname.min.js": [ "libraryname", "./node_modules/@xxxyyy/libraryname/types/index.d.ts" ]
    }
  }
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X