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?

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');

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.


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

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.


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.


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.


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


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,

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

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.


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';


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;

-4

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

var _ = require('your_module_name');
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.