No se pudo encontrar un archivo de declaración para el módulo 'nombre-módulo'. '/path/to/module-name.js' implícitamente tiene un tipo 'any'

303

Leí cómo TypeScript funciona la resolución del módulo .

Tengo el siguiente repositorio: @ ts-stack / di . Después de compilar la estructura del directorio es la siguiente:

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

En mi package.json escribí "main": "dist/index.js" .

En Node.js todo funciona bien, pero TypeScript:

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

No se pudo encontrar un archivo de declaración para el módulo '@ ts-stack / di'. '/path/to/node_modules/@ts-stack/di/dist/index.js' implícitamente tiene un tipo 'any'.

Y sin embargo, si importo de la siguiente manera, entonces todo funciona:

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

¿Qué estoy haciendo mal?

ktretyak
fuente

Respuestas:

295

Aquí hay otras dos soluciones.

Cuando un módulo no es suyo, intente instalar tipos desde @types:

npm install -D @types/module-name

Si los errores de instalación anteriores intentan cambiar las importdeclaraciones a require:

// import * as yourModuleName from 'module-name';
const yourModuleName = require('module-name');
ktretyak
fuente
13
Si no puede encontrar el nombre, ejecute esto para TypeScript 2.0:npm install @types/node --save-dev
Ogglas
120
¿Qué pasa si el módulo no tiene el paquete @types?
Daniel Kmak
37
Creo que usar en requirelugar de importes un poco anti-patrón: es mejor declarar el módulo en un .d.tsarchivo; mira mi respuesta a continuación.
Retsam
2
Ejemplo de uso: const mdbreact = require('mdbreact'); const { Button, Card, CardBody, CardText, CardTitle, CardImage } = mdbreact;
Sgedda
1
Este es un mal consejo. Esto niega totalmente el punto de TypeScript y la actitud general de FOSS de "algo bastante fácil vale la pena contribuir". Si falta escribir a, busque a alguien que lo haya hecho y no haya publicado o envíe un RP con sus tipings o no use un sistema de escritura si solo quiere evitarlo.
Dave Mackintosh
266

Si está importando un módulo de terceros 'foo'que no proporciona ninguna tipificación, ya sea en la propia biblioteca o en el @types/foopaquete (generado desde el repositorio DefinitelyTyped ), puede hacer que este error desaparezca declarando el módulo en un archivo con una .d.tsextensión. TypeScript busca .d.tsarchivos en los mismos lugares donde buscará .tsarchivos normales : como se especifica en "archivos", "incluir" y "excluir" en el tsconfig.json.

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

A continuación, cuando se importa foosólo va a escribir como any.


Alternativamente, si desea obtener sus propios tipos, también puede hacerlo:

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

Entonces esto se compilará correctamente:

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

No tiene que proporcionar tipificaciones completas para el módulo, solo lo suficiente para los bits que realmente está utilizando (y desea las tipificaciones adecuadas), por lo que es particularmente fácil de hacer si está utilizando una cantidad bastante pequeña de API.


Por otro lado, si no le importan los tipos de bibliotecas externas y desea importar todas las bibliotecas sin tipos any, puede agregar esto a un archivo con una .d.tsextensión:

declare module '*';

El beneficio (y el inconveniente) de esto es que puede importar absolutamente cualquier cosa y TS compilará.

Retsam
fuente
27
¿Dónde busca el compilador los d.tsarchivos? ¿Debería proporcionar alguna configuración como typeRoots?
Tom
17
@Tom Busca .d.tsarchivos en los mismos lugares que buscará .tsarchivos normales : como se especifica "archivos", "incluir" y "excluir" en el tsconfig.json. No recomendaría usar typeRootspara este propósito: está destinado a la ubicación de módulos de tipo externo (es decir node_modules/@types), no a .d.tsarchivos individuales .
Retsam
3
Me sale "archivo foo.d.ts no es un módulo"
Nathan H
2
Parece que este archivo comodín debe llamarse "typings.d.ts"
jacob
44
¿Dónde debo poner este .d.tsarchivo?
tonix
127

Si necesita una solución rápida, simplemente agregue esto antes de la línea de importación:

// @ts-ignore
Liran H
fuente
77
Gracias, la respuesta más útil para mi caso.
David
Esto causa un error en versiones posteriores de eslint:error Do not use "// @ts-ignore" comments because they suppress compilation errors @typescript-eslint/ban-ts-ignore
Hykilpikonna
91

Esa sensación cuando usted está buscando a cabo durante dos días y encontrar de esta manera: basta con retirar .jsa partir "main": "dist/index.js"de package.jsony todo funciona muy bien!

"main": "dist/index",

UPD : esta respuesta relativa si tiene su propio paquete npm, si no, vea mi respuesta a continuación .

Y si la respuesta anterior no resuelve el módulo de importación, trate sólo tiene que añadir typingsen package.json:

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

Por supuesto, aquí carpeta dist: es donde almacena los archivos de su módulo.

ktretyak
fuente
Llegué a su pregunta y su respuesta muchas veces estos últimos días y me gustaría agregar que lo que me faltaba era declarar esos tipos en un archivo .d.ts, por lo que, en mi caso, módulos de nodo instalados que venían sin Los tipos (y no pude instalar explícitamente sus tipos) comenzaron a funcionar declarándolos en ese archivo escribiendo "declare module 'MYDesiredModule'
Juan
Gracias. Agregar "typings": "dist / index", a mi package.json fue lo que funcionó para mí. Es extraño que VS Code arroje un error mecanografiado cuando ni siquiera estoy usando TypeScript
phocks
Gracias por tu perspicacia! ¿Podría decirme por qué las definiciones de VS Code no funcionan para mi propio paquete npm si intento ir a las definiciones? He creado una pregunta aquí y no he tenido suerte hasta ahora ... stackoverflow.com/questions/59128917/…
tonix
necesita agregar el archivo "index.d.ts" en la carpeta dist y ponerlo declare module "moduleName" mientras tanto
Sunny Sun
42

TypeScript básicamente está implementando reglas y agregando tipos a su código para hacerlo más claro y más preciso debido a la falta de restricciones en Javascript. TypeScript requiere que describa sus datos, para que el compilador pueda verificar su código y encontrar errores. El compilador le informará si está utilizando tipos no coincidentes, si está fuera de su alcance o si intenta devolver un tipo diferente. Por lo tanto, cuando utiliza bibliotecas y módulos externos con TypeScript, deben contener archivos que describan los tipos en ese código. Esos archivos se denominan archivos de declaración de tipo con una extensión d.ts. La mayoría de los tipos de declaración para los módulos npm ya están escritos y puede incluirlos usando npm install @types/module_name(donde module_name es el nombre del módulo cuyos tipos desea incluir).

Sin embargo, hay módulos que no tienen sus definiciones de tipo y para que el error desaparezca e importe el módulo usando import * as module_name from 'module-name', cree una carpeta typingsen la raíz de su proyecto, dentro cree una nueva carpeta con el nombre de su módulo y en ese carpeta crea un module_name.d.tsarchivo y escribe declare module 'module_name'. Después de esto, simplemente vaya a su tsconfig.jsonarchivo y agregue "typeRoots": [ "../../typings", "../../node_modules/@types"]el compilerOptions(con la ruta relativa adecuada a sus carpetas) para que TypeScript sepa dónde puede encontrar las definiciones de tipos de sus bibliotecas y módulos y agregar una nueva propiedad "exclude": ["../../node_modules", "../../typings"]al archivo. Aquí hay un ejemplo de cómo debería verse su archivo tsconfig.json:

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

Al hacer esto, el error desaparecerá y podrá apegarse a las últimas reglas de ES6 y TypeScript.

Marko Rochevski
fuente
Solo funcionó para mí si nombraba el archivo de tipings index.d.ts. Aparte de eso, esta fue la única solución que funcionó para mí.
Chris Haines
21

Para cualquier otra persona que lea esto, intente cambiar el nombre de su archivo .js a .ts

Editar: también puede agregar "allowJs": truea su archivo tsconfig.

Martin Lockett
fuente
Sí, tuve el mismo problema con los "gráficos de reacción de fusión" y esta solución funcionó de maravilla.
bostezando
16

Esta manera funciona para mí:

1. agregue su propia declaración en un archivo de declaración como index.d.ts (tal vez debajo de la raíz del proyecto)
declare module 'Injector';
2. agregue su 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
    }

- editar: comillas necesarias alrededor del nombre del módulo

Lumaskcete
fuente
4

Tuve el mismo problema al usar un módulo de nodo con una aplicación de reacción escrita en mecanografiado. El módulo se instaló correctamente usando npm i --save my-module. Está escrito en javascript y exporta una Clientclase.

Con:

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

La compilación falla con el error:

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-moduleno existe, así que agregué un my-module.d.tsarchivo al lado del que my-modulese importa, con la línea sugerida. Entonces recibí el error:

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

El cliente se exporta realmente y funciona normalmente si lo uso en una aplicación js. Además, el mensaje anterior me dice que el compilador está buscando en el archivo correcto ( /node_modules/my-module/lib/index.jsse define en el my-module/package.json "main"elemento).

Resolví el problema diciéndole al compilador que no me importa lo implícito any, es decir, configuré falsela siguiente línea del tsconfig.jsonarchivo:

    "noImplicitAny": false,
Kanthavel
fuente
14
Quiero decir, esto funciona, pero estás perdiendo la capacidad de escribir estrictamente el resto de tu código. No es una gran solución.
phillyslick
3

fácil de arreglar es:

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

si desea declarar la interfaz del objeto (Recomendado para un gran proyecto) puede usar:

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

¿Cómo usar eso? sencillo..

const x = require('foo') // or import x from 'foo'
x.getName() // intellisense can read this
Abdul Aziz Al Basyir
fuente
2

También estaba recibiendo esto, me desconcertó por un tiempo, incluso con el módulo y los tipos ya instalados y recargando mi IDE varias veces.

Lo que lo solucionó en mi caso fue terminar los procesos de la terminal, eliminar node_modules, borrar la memoria caché del administrador de paquetes de nodos y installvolver a cargar el editor.

León
fuente
2

Desafortunadamente está fuera de nuestras manos si el escritor del paquete se molesta con un archivo de declaración. Lo que tiendo a hacer es tener un archivo index.d.tsque contendrá todos los archivos de declaración que faltan de varios paquetes:

Index.ts:

declare module 'v-tooltip';
declare module 'parse5';
declare module 'emoji-mart-vue-fast';
Luke Garrigan
fuente
0

Esto es lo que funcionó de mí.

npm install --save readline

honkskillet
fuente
0

He intentado todo aquí, pero para mí fue un problema completamente diferente: tuve que eliminar de mis *.d.tsdeclaraciones de importación:

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

Después de eliminar el error desapareció ...

Aclaración : cuando declaramos un módulo en un *.d.tsarchivo, el compilador mecanografiado lo recoge automáticamente como un módulo ambiental (el que no necesita importar explícitamente). Una vez que especificamos import ... from ..., el archivo ahora se convierte en un módulo normal (ES6) y, por lo tanto, no se recogerá automáticamente. Por lo tanto, si aún desea que se comporte como un módulo ambiental , use un estilo de importación diferente de esta manera:

type MyType: import('3rd-party-module').SomeModuleType;
Ilyas Assainov
fuente
-4

Simplemente puede importarlo usando require como el siguiente código:

var _ = require('your_module_name');
Riyad Khalifeh
fuente