Não foi possível encontrar um arquivo de declaração para o módulo 'module-name'. '/path/to/module-name.js' tem implicitamente um tipo 'any'

303

Eu li como funciona a resolução do módulo TypeScript .

Eu tenho o seguinte repositório: @ ts-stack / di . Depois de compilar, a estrutura de diretórios é a seguinte:

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

No meu package.json eu escrevi "main": "dist/index.js".

No Node.js tudo funciona bem, mas o TypeScript:

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

Não foi possível encontrar um arquivo de declaração para o módulo '@ ts-stack / di'. '/path/to/node_modules/@ts-stack/di/dist/index.js' implicitamente tem um tipo 'any'.

E, no entanto, se eu importar da seguinte maneira, tudo funcionará:

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

O que estou fazendo de errado?

ktretyak
fonte

Respostas:

295

Aqui estão duas outras soluções

Quando um módulo não é seu - tente instalar tipos de @types:

npm install -D @types/module-name

Se os erros acima instalarem - tente alterar as importinstruções para require:

// import * as yourModuleName from 'module-name';
const yourModuleName = require('module-name');
ktretyak
fonte
13
Se você não conseguir encontrar o nome, execute o TypeScript 2.0:npm install @types/node --save-dev
Ogglas 19/17
120
E se o módulo não tiver o pacote @types?
precisa
37
Eu acho que usar em requirevez de importé um pouco antipadrão: é melhor declarar o módulo em um .d.tsarquivo; veja minha resposta abaixo.
Retsam
2
Exemplo de uso: const mdbreact = require('mdbreact'); const { Button, Card, CardBody, CardText, CardTitle, CardImage } = mdbreact;
Sgedda 20/09/18
1
Este é um péssimo conselho. Isso nega totalmente o ponto do TypeScript e a atitude geral do software livre de "algo fácil o suficiente vale a pena contribuir". Se estiver faltando digitar a, a pesquisa de alguém fez isso e não publicou ou envie um PR com suas digitações ou não use um sistema de digitação se você quiser contorná-lo.
Dave Mackintosh
266

Se você estiver importando um módulo de terceiros 'foo'que não fornece nenhuma digitação, na própria biblioteca ou no @types/foopacote (gerado a partir do repositório DefinitelyTyped ), poderá fazer com que esse erro desapareça, declarando o módulo em um arquivo com uma .d.tsextensão. O TypeScript procura .d.tsarquivos nos mesmos locais em que procurará .tsarquivos normais : conforme especificado em "arquivos", "incluir" e "excluir" no tsconfig.json.

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

Então, quando você importar, fooele será digitado como any.


Como alternativa, se você quiser rolar suas próprias digitações, poderá fazer isso também:

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

Então isso será compilado corretamente:

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

Você não precisa fornecer digitações completas para o módulo, apenas o suficiente para os bits que realmente está usando (e deseja digitações apropriadas), por isso é particularmente fácil se você estiver usando uma quantidade bastante pequena de API.


Por outro lado, se você não se importa com as tipologias de bibliotecas externas e deseja que todas as bibliotecas sem tipagens sejam importadas any, adicione-o a um arquivo com uma .d.tsextensão:

declare module '*';

A vantagem (e a desvantagem) disso é que você pode importar absolutamente tudo e o TS será compilado.

Retsam
fonte
27
onde o compilador procura d.tsarquivos? você deve fornecer alguma configuração como typeRoots?
Tom
17
@ Tom Ele procura por .d.tsarquivos nos mesmos locais em que procurará por .tsarquivos normais : como "arquivos" especificados, "incluem" e "excluem" no tsconfig.json. Eu não recomendaria o uso typeRootspara esse fim: isso se destina à localização de módulos de tipo externo (ou seja node_modules/@types), não de .d.tsarquivos individuais .
Retsam 17/07/2018
3
Eu recebo "o arquivo foo.d.ts não é um módulo"
Nathan H #
2
Parece que este arquivo curinga precisa ser chamado "typings.d.ts"
jacob
4
Onde devo colocar esse .d.tsarquivo?
tonix 27/12/19
127

Se você precisar de uma solução rápida, basta adicioná-lo antes da linha de sua importação:

// @ts-ignore
Liran H
fonte
7
Obrigado, resposta mais útil para o meu caso.
David
Isso causa um erro nas versões posteriores do eslint:error Do not use "// @ts-ignore" comments because they suppress compilation errors @typescript-eslint/ban-ts-ignore
Hykilpikonna
91

Essa sensação quando você fica olhando por dois dias e fica assim: basta remover .jsde "main": "dist/index.js"dentro package.jsone tudo funciona bem!

"main": "dist/index",

UPD : esta resposta é relativa se você tiver seu próprio pacote npm, se não - veja minha resposta abaixo .

E se a resposta acima não resolvidos importação seu módulo, tente apenas adicionar typingsem package.json:

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

Obviamente, aqui pasta dist- é onde você armazena os arquivos do módulo.

ktretyak
fonte
Eu vim para sua pergunta e sua resposta várias vezes nos últimos dias e gostaria de acrescentar que o que estava faltando era declarar esses tipos em um arquivo .d.ts; portanto, no meu caso, instalei módulos de nó que vieram sem tipos (e eu era incapaz de instalar explicitamente os seus tipos) começou a trabalhar, declarando-os no arquivo escrevendo "módulo declarar 'MYDesiredModule'
Juan
Obrigado. Adicionando "typings": "dist / index" ao meu package.json foi o que funcionou para mim. Estranho que Código VS lança um erro typescript quando não estou mesmo usando texto datilografado
phocks
Obrigado pela sua compreensão! Você poderia me dizer por que as definições do código VS não funcionam para o meu próprio pacote npm se eu tentar ir para as definições? Criei uma pergunta aqui e não tive sorte até agora ... stackoverflow.com/questions/59128917/…
tonix
você precisa adicionar o arquivo "index.d.ts" na pasta dist e, declare module "moduleName" enquanto isso, colocar
Sunny Sun
42

O TypeScript está basicamente implementando regras e adicionando tipos ao seu código para torná-lo mais claro e preciso devido à falta de restrições no Javascript. O TypeScript exige que você descreva seus dados, para que o compilador possa verificar seu código e encontrar erros. O compilador informará se você está usando tipos incompatíveis, se está fora do seu escopo ou tenta retornar um tipo diferente. Portanto, quando você usa bibliotecas e módulos externos com o TypeScript, eles precisam conter arquivos que descrevam os tipos nesse código. Esses arquivos são chamados de arquivos de declaração de tipo com uma extensão d.ts. A maioria dos tipos de declaração para módulos npm já está gravada e você pode incluí-los usando npm install @types/module_name(onde module_name é o nome do módulo cujos tipos você deseja incluir).

No entanto, existem módulos que não têm suas definições de tipo e, para que o erro desapareça e importe o módulo usando import * as module_name from 'module-name', crie uma pasta typingsna raiz do seu projeto, crie uma nova pasta com o nome do módulo e nesse pasta crie um module_name.d.tsarquivo e escreva declare module 'module_name'. Depois disso, basta ir ao seu tsconfig.jsonarquivo e adicionar "typeRoots": [ "../../typings", "../../node_modules/@types"]o compilerOptions(com o caminho relativo apropriado para suas pastas) para permitir que o TypeScript saiba onde ele pode encontrar as definições de tipos de suas bibliotecas e módulos e adicionar uma nova propriedade "exclude": ["../../node_modules", "../../typings"]ao arquivo. Aqui está um exemplo de como o seu arquivo tsconfig.json deve ficar:

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

Ao fazer isso, o erro desaparecerá e você poderá seguir as regras mais recentes do ES6 e do TypeScript.

Marko Rochevski
fonte
Só funcionou para mim se eu nomeasse o arquivo de digitações index.d.ts. Fora isso, essa foi a única solução que funcionou para mim.
Chris Haines
21

Para qualquer pessoa que esteja lendo isso, tente renomear o arquivo .js para .ts

Editar: Você também pode adicionar "allowJs": trueao seu arquivo tsconfig.

Martin Lockett
fonte
Sim, tive o mesmo problema com "react-fusioncharts" e esta solução funcionou como um encanto.
yawningphantom 11/02
16

Dessa forma, funciona para mim:

1. adicione sua própria declaração em um arquivo de declaração como index.d.ts (talvez na raiz do projeto)
declare module 'Injector';
2. adicione seu index.d.ts ao 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: aspas necessárias em torno do nome do módulo

Lumaskcete
fonte
4

Eu tive o mesmo problema usando um módulo de nó com um aplicativo de reação escrito em texto datilografado. O módulo foi instalado com sucesso usando npm i --save my-module. Está escrito em javascript e exporta uma Clientclasse.

Com:

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

A compilação falha com o erro:

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-modulenão existe, então adicionei um my-module.d.tsarquivo ao lado do onde my-moduleé importado, com a linha sugerida. Eu recebi o erro:

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

O cliente é realmente exportado e funciona normalmente se eu o usar em um aplicativo js. Além disso, a mensagem anterior me diz que o compilador está procurando no arquivo certo ( /node_modules/my-module/lib/index.jsestá definido no my-module/package.json "main"elemento).

Resolvi o problema dizendo ao compilador que não me importo com implícito any, ou seja, defino falsea seguinte linha do tsconfig.jsonarquivo:

    "noImplicitAny": false,
Kanthavel
fonte
14
Quero dizer, isso funciona, mas você está perdendo a capacidade de digitar estritamente o restante do seu código. Não é uma ótima solução alternativa.
precisa saber é o seguinte
3

simples de consertar é:

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

se você deseja declarar a interface do objeto (recomendável para um grande projeto), você pode usar:

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

Como usar isso? simples..

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

Eu também estava entendendo isso, fiquei confuso por um tempo, mesmo com o módulo e os tipos já instalados e recarregando meu IDE várias vezes.

O que o corrigiu no meu caso foi encerrar os processos do terminal, remover node_modules, limpar o cache do gerenciador de pacotes do nó e fazer um novo installcarregamento e, em seguida, recarregar o editor.

Leo
fonte
2

Infelizmente, está fora de nossas mãos se o gravador de pacotes se incomoda com um arquivo de declaração. O que costumo fazer é ter um arquivo index.d.tsque contenha todos os arquivos de declaração ausentes de vários pacotes:

Index.ts:

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

Foi isso que funcionou comigo.

npm install --save readline

honkskillet
fonte
0

Eu tentei de tudo aqui, mas para mim foi um problema completamente diferente: tive que remover das minhas *.d.tsinstruções de importação:

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

Depois de remover o erro foi embora ...

Esclarecimento : Quando declaramos um módulo em um *.d.tsarquivo, ele é automaticamente escolhido pelo compilador Typescript como um módulo ambiente (aquele que você não precisa importar explicitamente). Depois de especificar o import ... from ..., o arquivo agora se torna um módulo normal (ES6) e, portanto, não será coletado automaticamente. Portanto, se você ainda deseja que ele se comporte como um módulo ambiente , use um estilo de importação diferente, como:

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

Simplesmente você pode importá-lo usando o seguinte código:

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