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 :
- Un "polyfill" parce que les définitions intégrées de Window de TypeScript manquent de certaines choses.
- window.CustomEventListener : voir https://github.com/microsoft/TypeScript/issues/28357
- window.ResizeObserverEntry : voir https://github.com/microsoft/TypeScript/issues/37861
- 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.