Impossibile trovare un file di dichiarazione per il modulo 'nome-modulo'. '/path/to/module-name.js' ha implicitamente un tipo 'qualunque'


303

Ho letto come funziona la risoluzione del modulo TypeScript .

Ho il seguente repository: @ ts-stack / di . Dopo aver compilato la struttura delle directory è la seguente:

├── 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

Nel mio package.json ho scritto "main": "dist/index.js".

In Node.js tutto funziona bene, ma TypeScript:

import {Injector} from '@ts-stack/di';

Impossibile trovare un file di dichiarazione per il modulo '@ ts-stack / di'. '/path/to/node_modules/@ts-stack/di/dist/index.js' ha implicitamente un tipo 'qualunque'.

Eppure, se importerò come segue, allora tutto funziona:

import {Injector} from '/path/to/node_modules/@ts-stack/di/dist/index.js';

Che cosa sto facendo di sbagliato?

Risposte:


295

Ecco altre due soluzioni

Quando un modulo non è tuo, prova a installare i tipi da @types:

npm install -D @types/module-name

Se i suddetti errori di installazione, prova a modificare le importistruzioni in require:

// import * as yourModuleName from 'module-name';
const yourModuleName = require('module-name');

13
Se non riesci a trovare il nome, devi eseguirlo per TypeScript 2.0:npm install @types/node --save-dev
Ogglas,

120
Cosa succede se il modulo non ha il pacchetto @types?
Daniel Kmak,

37
Penso che usare al requireposto di importsia un po 'un anti-pattern: è meglio dichiarare il modulo in un .d.tsfile; vedi la mia risposta qui sotto.
Retsam,

2
Esempio di utilizzo: const mdbreact = require('mdbreact'); const { Button, Card, CardBody, CardText, CardTitle, CardImage } = mdbreact;
Sgedda

1
Questo è un consiglio scadente. Ciò nega totalmente il punto di TypeScript e l'atteggiamento generale FOSS di "qualcosa che è abbastanza semplice vale la pena contribuire". Se manca una digitazione a, la ricerca di qualcuno l'ha eseguita e non ha pubblicato o inviato un PR con le tue digitazioni o non utilizzare un sistema di digitazione se si desidera solo aggirarlo.
Dave Mackintosh,

266

Se stai importando un modulo di terze parti 'foo'che non fornisce alcuna digitazione, né nella libreria stessa o nel @types/foopacchetto (generato dal repository DefinitelyTyped ), puoi eliminare questo errore dichiarando il modulo in un file con .d.tsestensione. TypeScript cerca i .d.tsfile negli stessi punti in cui cercherà i .tsfile normali : come specificato in "file", "include" ed "escludi" in tsconfig.json.

// foo.d.ts
declare module 'foo';

Quindi quando lo importi fooverrà semplicemente digitato come any.


In alternativa, se vuoi inserire le tue digitazioni puoi farlo anche tu:

// foo.d.ts
declare module 'foo' {
    export function getRandomNumber(): number
} 

Quindi questo verrà compilato correttamente:

import { getRandomNumber } from 'foo';
const x = getRandomNumber(); // x is inferred as number

Non è necessario fornire digitazioni complete per il modulo, quanto basta per i bit che si stanno effettivamente utilizzando (e si desidera digitare correttamente), quindi è particolarmente facile se si utilizza una quantità abbastanza piccola di API.


D'altra parte, se non ti interessano le tipizzazioni di librerie esterne e vuoi che tutte le librerie senza tipizzazioni vengano importate come any, puoi aggiungerlo a un file con .d.tsestensione:

declare module '*';

Il vantaggio (e il rovescio della medaglia) di questo è che puoi importare assolutamente qualsiasi cosa e TS compilerà.


27
dove cerca i d.tsfile il compilatore ? dovresti fornire una configurazione come typeRoots?
Tom,

17
@ Tom Cerca i .d.tsfile negli stessi punti in cui cercherà i .tsfile normali : come specificato "file", "include" ed "escludi" in tsconfig.json. Non consiglierei di usarlo typeRootsper questo scopo: è inteso per la posizione di moduli di tipo esterni (cioè node_modules/@types), non singoli .d.tsfile.
Retsam,

3
Ottengo "il file foo.d.ts non è un modulo"
Nathan H,

2
Sembra che questo file jolly debba essere chiamato "typings.d.ts"
jacob

4
Dove devo mettere questo .d.tsfile?
tonix,

127

Se hai bisogno di una soluzione rapida, aggiungilo semplicemente prima della riga dell'importazione:

// @ts-ignore

7
Grazie, la risposta più utile per il mio caso.
David,

Ciò causa un errore nelle versioni successive di eslint:error Do not use "// @ts-ignore" comments because they suppress compilation errors @typescript-eslint/ban-ts-ignore
Hykilpikonna,

91

Quella sensazione quando stai guardando fuori per due giorni e lo trovi in ​​questo modo: basta rimuovere .jsda "main": "dist/index.js"dentro package.jsone tutto funziona bene!

"main": "dist/index",

UPD : questa risposta relativa se hai il tuo pacchetto npm, in caso contrario - vedi la mia risposta di seguito .

E se la risposta di cui sopra non risolve il modulo di importazione, provare basta aggiungere typingsin package.json:

"main": "dist/index",
"typings": "dist/index",

Naturalmente, qui la cartella dist: è dove vengono archiviati i file del modulo.


Sono arrivato alla tua domanda e alla tua risposta molte volte negli ultimi giorni e vorrei aggiungere che ciò che mi mancava era dichiarare quei tipi in un file .d.ts, quindi, nel mio caso, ho installato i moduli del nodo che sono arrivati ​​senza tipi (e non sono stato in grado di installare esplicitamente i loro tipi) hanno iniziato a funzionare dichiarandoli in quel file scrivendo "dichiarare il modulo 'MYDesiredModule'
Juan

Grazie. Aggiungendo "typings": "dist / index", al mio package.json è stato quello che ha funzionato per me. Strano che VS Code generi un errore dattiloscritto quando non sto nemmeno usando TypeScript
phocks

Grazie per la tua comprensione! Potresti dirmi perché le definizioni VS Code non funzionano per il mio pacchetto npm se provo ad andare alle definizioni? Ho creato una domanda qui e non ha avuto fortuna finora ... stackoverflow.com/questions/59128917/...
tonix

è necessario aggiungere il file "index.d.ts" nella cartella dist e declare module "moduleName" nel frattempo inserire
Sunny Sun

42

TypeScript sta fondamentalmente implementando regole e aggiungendo tipi al codice per renderlo più chiaro e più accurato a causa della mancanza di vincoli in Javascript. TypeScript richiede di descrivere i tuoi dati, in modo che il compilatore possa controllare il tuo codice e trovare errori. Il compilatore ti farà sapere se stai usando tipi non corrispondenti, se sei fuori dal tuo ambito o provi a restituire un tipo diverso. Pertanto, quando si utilizzano librerie e moduli esterni con TypeScript, devono contenere file che descrivono i tipi in quel codice. Tali file sono chiamati file di dichiarazione del tipo con estensione d.ts. La maggior parte dei tipi di dichiarazione per i moduli npm sono già scritti e puoi includerli usando npm install @types/module_name(dove module_name è il nome del modulo di cui vuoi includere i tipi).

Tuttavia, ci sono moduli che non hanno le definizioni dei tipi e per far sparire l'errore e importare il modulo usando import * as module_name from 'module-name', crea una cartella typingsnella radice del tuo progetto, dentro crea una nuova cartella con il nome del tuo modulo e in quello cartella crea un module_name.d.tsfile e scrivi declare module 'module_name'. Dopo questo basta andare al tuo tsconfig.jsonfile e aggiungere "typeRoots": [ "../../typings", "../../node_modules/@types"]il compilerOptions(con il relativo percorso relativo alle tue cartelle) per far sapere a TypeScript dove può trovare le definizioni dei tipi delle tue librerie e moduli e aggiungere una nuova proprietà "exclude": ["../../node_modules", "../../typings"]al file. Ecco un esempio di come dovrebbe apparire il tuo file tsconfig.json:

{
    "compilerOptions": {
        "module": "commonjs",
        "noImplicitAny": true,
        "sourceMap": true,
        "outDir": "../dst/",
        "target": "ESNEXT",
        "typeRoots": [
            "../../typings",
            "../../node_modules/@types"
        ]
    },
    "lib": [
            "es2016"
    ],
    "exclude": [
        "../../node_modules",
        "../../typings"
    ]
}

In questo modo, l'errore scompare e si sarà in grado di attenersi alle ultime regole ES6 e TypeScript.


Ha funzionato solo per me se ho chiamato il file delle tipizzazioni index.d.ts. A parte questo, questa è stata l'unica soluzione che ha funzionato a 360 gradi per me.
Chris Haines il

21

Per chiunque legga questo, prova a rinominare il tuo file .js in .ts

Modifica: puoi anche aggiungere "allowJs": trueal tuo file tsconfig.


sì, aveva lo stesso problema con "reagenti a fusione" e questa soluzione funzionava come un incantesimo.
sbadiglio fantasma l'

16

In questo modo funziona per me:

1. aggiungi la tua dichiarazione in un file di dichiarazione come index.d.ts (magari sotto la radice del progetto)
declare module 'Injector';
2. aggiungi il tuo index.d.ts a tsconfig.json
  {
    "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
    }

- modifica: virgolette necessarie intorno al nome del modulo


4

Ho avuto lo stesso problema utilizzando un modulo nodo con un'applicazione di reazione scritta in dattiloscritto. Il modulo è stato installato correttamente utilizzando npm i --save my-module. È scritto in javascript ed esporta una Clientclasse.

Con:

import * as MyModule from 'my-module';
let client: MyModule.Client = new MyModule.Client();

La compilazione non riesce con l'errore:

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-modulenon esiste, quindi ho aggiunto un my-module.d.tsfile accanto a quello in cui my-moduleviene importato, con la riga suggerita. Ho quindi ricevuto l'errore:

Namespace '"my-module"' has no exported member 'Client'.

Il client viene effettivamente esportato e funziona normalmente se lo uso in un'app js. Inoltre, il messaggio precedente mi dice che il compilatore sta cercando nel file giusto ( /node_modules/my-module/lib/index.jsè definito my-module/package.json "main"nell'elemento).

Ho risolto il problema dicendo al compilatore che non mi importa di implicito any, cioè ho impostato falsela seguente riga del tsconfig.jsonfile:

    "noImplicitAny": false,

14
Voglio dire, funziona, ma stai perdendo la possibilità di digitare rigorosamente il resto del codice. Non è un'ottima soluzione.
Phillyslick,

3

semplice da risolvere è:

// example.d.ts
declare module 'foo';

se vuoi dichiarare l'interfaccia dell'oggetto (Raccomandare per un grande progetto) puoi usare:

// example.d.ts
declare module 'foo'{
    // example
    export function getName(): string
}

Come usarlo? semplice..

const x = require('foo') // or import x from 'foo'
x.getName() // intellisense can read this

2

Anch'io stavo ottenendo questo, mi ha lasciato perplesso per un po ', anche con il modulo e i tipi già installati e ricaricando il mio IDE più volte.

Ciò che lo risolveva nel mio caso era terminare i processi terminali, rimuovere node_modules, svuotare la cache del gestore pacchetti nodo e fare un nuovo installcaricamento quindi l'editor.


2

Sfortunatamente non è nelle nostre mani se l'autore del pacchetto dà fastidio con un file di dichiarazione. Quello che tendo a fare è avere un file tale index.d.tsche conterrà tutti i file di dichiarazione mancanti da vari pacchetti:

Index.ts:

declare module 'v-tooltip';
declare module 'parse5';
declare module 'emoji-mart-vue-fast';

0

Questo è ciò che ha funzionato da me.

npm install --save readline


0

Ho provato di tutto qui, ma per me è stato un problema completamente diverso: ho dovuto rimuovere dalle mie *.d.tsdichiarazioni di importazione:

import { SomeModuleType } from '3rd-party-module';

Dopo aver rimosso l'errore è andato via ...

Chiarimento : quando dichiariamo un modulo in un *.d.tsfile, questo viene automaticamente raccolto dal compilatore Typescript come modulo ambientale (quello che non è necessario importare esplicitamente). Una volta specificato il import ... from ..., il file diventa ora un normale modulo (ES6) e quindi non verrà raccolto automaticamente. Quindi se vuoi ancora che si comporti come un modulo ambientale , usa uno stile di importazione diverso in questo modo:

type MyType: import('3rd-party-module').SomeModuleType;

-4

Semplicemente puoi importarlo usando il seguente codice:

var _ = require('your_module_name');
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.