Je lis comment TypeScript résolution du module fonctionne.
J'ai le référentiel suivant: ts-di . Après avoir compilé la structure des répertoires, procédez comme suit:
├── dist
│ ├── annotations.d.ts
│ ├── annotations.js
│ ├── index.d.ts
│ ├── index.js
│ ├── injector.d.ts
│ ├── injector.js
│ ├── profiler.d.ts
│ ├── profiler.js
│ ├── providers.d.ts
│ ├── providers.js
│ ├── util.d.ts
│ └── util.js
├── LICENSE
├── package.json
├── README.md
├── src
│ ├── annotations.ts
│ ├── index.ts
│ ├── injector.ts
│ ├── profiler.ts
│ ├── providers.ts
│ └── util.ts
└── tsconfig.json
Dans mon package.json j'ai écrit "main": "dist/index.js"
.
Dans Node.js, tout fonctionne bien, mais TypeScript:
import {Injector} from 'ts-di';
Impossible de trouver un fichier de déclaration pour le module 'ts-di'. '/path/to/node_modules/ts-di/dist/index.js' a implicitement un type 'quelconque'.
Et pourtant, si j'importe comme suit, alors tout fonctionne:
import {Injector} from '/path/to/node_modules/ts-di/dist/index.js';
Qu'est-ce que je fais mal?
Ce sentiment lorsque vous recherchez deux jours et que vous le trouvez comme ceci: supprimez simplement .js
de "main": "dist/index.js"
dans package.json
et tout fonctionne correctement!
"main": "dist/index",
UPD: cette réponse est relative si vous avez votre propre paquet npm, sinon - voyez ma réponse ci-dessous .
Et si la réponse ci-dessus n’est pas résolue, importez votre module, essayez simplement d’ajouter typings
dans package.json
:
"main": "dist/index",
"typings": "dist/index",
Bien sûr, ici le dossier dist
- c’est là où sont stockés les fichiers de votre module.
Encore un autre moyen, quand un module ne vous appartient pas - essayez simplement de l’installer à partir de @types
:
npm install -D @types/module-name
Ou, si installation est erronée, essayez de réécrire import
en require
:
// import * as yourModuleName from 'module-name';
const yourModuleName = require('module-name');
Si vous importez un module tiers 'foo'
qui ne fournit aucun typage, ni dans la bibliothèque elle-même, ni dans le package @types/foo
(généré à partir du répertoire DefinitelyTyped ,), vous pouvez éliminer cette erreur. en déclarant le module dans un fichier .d.ts
:
// foo.d.ts
declare module 'foo';
Ensuite, lorsque vous importez foo
, il vous suffira de saisir any
.
Alternativement, si vous voulez rouler vos propres frappe, vous pouvez aussi le faire:
// foo.d.ts
declare module 'foo' {
export function getRandomNumber(): number
}
Alors ceci compilera correctement:
import { getRandomNumber } from 'foo';
const x = getRandomNumber(); // x is inferred as number
Il n'est pas nécessaire de fournir des saisies complètes pour le module, mais juste assez pour les bits que vous utilisez réellement (et que vous souhaitez saisir correctement), il est donc particulièrement facile de le faire si vous utilisez une quantité relativement petite d'API.
D'autre part, si vous ne vous souciez pas des typages de bibliothèques externes et que vous souhaitez que toutes les bibliothèques sans typages soient importées en tant que any
, vous pouvez ajouter ceci à un fichier .d.ts
:
declare module '*';
L'avantage (et l'inconvénient) de ceci est que vous pouvez importer absolument n'importe quoi et que TS compilera.
TypeScript implémente des règles et ajoute des types à votre code pour le rendre plus clair et plus précis en raison de l'absence de contraintes en Javascript. TypeScript nécessite que vous décriviez vos données afin que le compilateur puisse vérifier votre code et rechercher les erreurs. Le compilateur vous indiquera si vous utilisez des types incompatibles, si vous êtes hors de portée ou si vous essayez de renvoyer un type différent . Ainsi, lorsque vous utilisez des bibliothèques et des modules externes avec TypeScript, ils doivent contenir des fichiers. qui décrivent les types dans ce code. Ces fichiers sont appelés types de fichiers de déclaration avec une extension d.ts
. La plupart des types de déclaration des modules npm sont déjà écrits et vous pouvez les inclure à l'aide de npm install @types/module_name
(nom_module étant le nom du module dont vous souhaitez inclure les types).
Cependant, certains modules n’ont pas de définition de type. Pour supprimer l’erreur et importer le module à l’aide de import * as module_name from 'module-name'
, créez un dossier typings
à la racine de votre projet, puis créez un nouveau dossier avec le nom et le nom de votre module. dans ce dossier, créez un fichier module_name.d.ts
et écrivez declare module 'module_name'
. Après cela, allez simplement dans votre fichier tsconfig.json
et ajoutez "typeRoots": [ "../../typings", "../../node_modules/@types"]
dans la compilerOptions
(avec le chemin relatif correct de vos dossiers) pour indiquer à TypeScript où il peut trouver les définitions de types de vos bibliothèques et modules et ajouter une nouvelle propriété "exclude": ["../../node_modules", "../../typings"]
au fichier. Voici un exemple de la manière dont votre fichier tsconfig.json devrait ressembler à ceci:
{
"compilerOptions": {
"module": "commonjs",
"noImplicitAny": true,
"sourceMap": true,
"outDir": "../dst/",
"target": "ESNEXT",
"typeRoots": [
"../../typings",
"../../node_modules/@types"
]
},
"lib": [
"es2016"
],
"exclude": [
"../../node_modules",
"../../typings"
]
}
En faisant cela, l'erreur disparaîtra et vous pourrez vous en tenir aux dernières règles ES6 et TypeScript.
Si vous avez besoin d'une solution rapide, ajoutez simplement ceci avant votre importation:
// @ts-ignore
J'ai eu le même problème en utilisant un module de noeud avec une application de réaction écrite en TypeScript. Le module a été installé avec succès avec npm i --save my-module
. Il est écrit en javascript et exporte une classe Client
.
Avec:
import * as MyModule from 'my-module';
let client: MyModule.Client = new MyModule.Client();
La compilation échoue avec l'erreur suivante:
Could not find a declaration file for module 'my-module'.
'[...]/node_modules/my-module/lib/index.js' implicitly has an 'any' type.
Try `npm install @types/my-module` if it exists or add a new declaration (.d.ts) file containing `declare module 'my-module';`
@types/my-module
n'existe pas, j'ai donc ajouté un fichier my-module.d.ts
à côté de celui où my-module
est importé, avec la ligne suggérée. J'ai ensuite eu l'erreur:
Namespace '"my-module"' has no exported member 'Client'.
Le client est effectivement exporté et fonctionne normalement si je l’utilise dans une application js. De plus, le message précédent me dit que le compilateur cherche dans le bon fichier (/node_modules/my-module/lib/index.js
est défini dans l'élément my-module/package.json
"main"
).
J'ai résolu le problème en disant au compilateur que je me fichais de la variable any
implicite, c'est-à-dire que j'avais défini la variable false
sur la ligne suivante du fichier tsconfig.json
:
"noImplicitAny": false,
Cette façon fonctionne pour moi:
declare module Injector;
{
"compilerOptions": {
"strictNullChecks": true,
"moduleResolution": "node",
"jsx": "react",
"noUnusedParameters": true,
"noUnusedLocals": true,
"allowSyntheticDefaultImports":true,
"target": "es5",
"module": "ES2015",
"declaration": true,
"outDir": "./lib",
"noImplicitAny": true,
"importHelpers": true
},
"include": [
"src/**/*",
"index.d.ts", // declaration file path
],
"compileOnSave": false
}
npm install --save TypeScript @types/node @types/react @types/react-dom @types/jest
yarn add TypeScript @types/node @types/react @types/react-dom @types/jest
J'avais aussi ce problème, m'avait laissé perplexe pendant un moment, même avec le module et les types déjà installés et en rechargeant mon IDE plusieurs fois.
Ce qui a réglé le problème, dans mon cas, a été de mettre fin aux processus de terminal, de supprimer node_modules
, d'effacer le cache du gestionnaire de packages de noeud, d'effectuer une nouvelle modification install
, puis de recharger l'éditeur.
J'importais Button de react-native-button et il donnait cette erreur comme le montre l'image:
Je fais le tour. Je suis arrivé au dossier node_modules/react-native-button/et j'ai copié le contenu du fichier Button.js. Créez un nouveau fichier nommé Button.d.ts et collez-y le contenu. Enregistré et l'erreur a disparu! Je ne connais pas la raison mais pour l'instant, il est parti!