'Module-name' modülü için bir bildirim dosyası bulunamadı. '/path/to/module-name.js' örtük olarak bir 'herhangi' türüne sahiptir


304

TypeScript modül çözünürlüğünün nasıl çalıştığını okudum .

Aşağıdaki depom var: @ ts-stack / di . Derleme yapıldıktan sonra dizin yapısı aşağıdaki gibidir:

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

Paketimde "main": "dist/index.js". Json yazdım .

Node.js'de her şey iyi çalışır, ancak TypeScript:

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

'@ Ts-stack / di' modülü için bir bildirim dosyası bulunamadı. '/path/to/node_modules/@ts-stack/di/dist/index.js' örtük olarak bir 'herhangi' türüne sahiptir.

Yine de, aşağıdaki gibi içe aktarırsam, her şey işe yarar:

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

Neyi yanlış yapıyorum?

Yanıtlar:


294

İşte diğer iki çözüm

Bir modül size ait olmadığında - aşağıdakilerden türleri yüklemeyi deneyin @types:

npm install -D @types/module-name

Yukarıdaki yükleme hataları varsa - importifadeleri şu şekilde değiştirmeyi deneyin require:

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

13
Eğer ad bulamazsanız TypeScript 2.0 için bunu çalıştırın:npm install @types/node --save-dev
Ogglas

122
Modülün @types paketi yoksa ne olur?
Daniel Kmak

37
Bunun requireyerine kullanmak importbir anti-desen biraz olduğunu düşünüyorum : modül bir .d.tsdosyada bildirmek daha iyidir ; aşağıdaki cevabımı gör.
Retsam

2
Örnek kullanım:const mdbreact = require('mdbreact'); const { Button, Card, CardBody, CardText, CardTitle, CardImage } = mdbreact;
Sgedda

1
Bu kötü bir tavsiye. Bu, TypeScript'in noktasını ve "yeterince kolay bir şeyin katkıda bulunmaya değer" genel FOSS tutumunu tamamen ortadan kaldırmaktadır. Eğer eksik yazım varsa, birini aramış ve yayınlamamış ya da yazdıklarınızla birlikte bir PR göndermeniz ya da sadece atlatmak istiyorsanız yazım sistemini kullanmamanız gerekir.
Dave Mackintosh

267

'foo'Kütüphanenin kendisinde veya @types/foopakette ( DefinitelyTyped deposundan oluşturulan ) herhangi bir tür belirtme sağlamayan üçüncü taraf bir modülü içe aktarıyorsanız , modülü bir modülde bildirerek bu hatayı ortadan kaldırabilirsiniz. dosya .d.tsuzantısı. TypeScript .d.ts, normal .tsdosyalar için arayacağı yerlerin aynısını arar : "files", "include" ve "exclude" altında tsconfig.json.

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

Sonra içe fooaktardığınızda sadece olarak yazılır any.


Alternatif olarak, kendi yazılarınızı almak istiyorsanız bunu da yapabilirsiniz:

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

Sonra bu doğru bir şekilde derlenecektir:

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

Modül için tam yazımları sağlamanız gerekmez, sadece kullandığınız bitler için yeterlidir (ve uygun yazımları ister), bu nedenle oldukça az miktarda API kullanıyorsanız, bunu yapmak özellikle kolaydır.


Öte yandan, harici kitaplıkların yazımlarıyla ilgilenmiyorsanız ve yazımları olmayan tüm kitaplıkların içe aktarılmasını anyistiyorsanız, bunu bir .d.tsuzantıya sahip bir dosyaya ekleyebilirsiniz :

declare module '*';

Bunun yararı (ve dezavantajı) kesinlikle her şeyi ithal edebilmeniz ve TS'in derlenmesidir.


28
derleyici d.tsdosyaları nerede arar ? gibi herhangi bir yapılandırma sağlamak gerekir typeRoots?
Tom

17
@Tom .d.tsNormal .tsdosyaları arayacağı yerlerin aynısını arar : belirtilen "files", "include" ve "exclude" öğelerinde tsconfig.json. typeRootsBu amaç için kullanılmasını önermem: bu harici tip modüllerin (yani node_modules/@types) konumu için ayrı ayrı değil .d.ts.
18:13 de Retsam

3
"Dosya foo.d.ts bir modül değil" alıyorum
Nathan H

2
Bu joker dosyaya "typings.d.ts" denilmesi gerekiyor gibi görünüyor
jacob

4
Bu .d.tsdosyayı nereye koymalıyım ?
tonix

127

Hızlı bir düzeltmeye ihtiyacınız varsa, bunu içe aktarma satırınızdan önce eklemeniz yeterlidir:

// @ts-ignore

7
Teşekkürler, davam için en yararlı cevap.
David

Bu eslint sonraki sürümlerinde bir hataya neden olur:error Do not use "// @ts-ignore" comments because they suppress compilation errors @typescript-eslint/ban-ts-ignore
Hykilpikonna

92

Sadece kaldırmak: İki gündür bakan ve böyle bulmak zaman duygu Yani .jsgelen "main": "dist/index.js"içinde package.jsonve herşey yolunda çalışıyor!

"main": "dist/index",

UPD : eğer kendi npm paketiniz varsa bu cevap göreceli - eğer cevabımı aşağıya bakınız .

Yukarıdaki cevap ithalat Modülünüzü çözülmezse eğer, sadece eklemek deneyin typingsiçinde package.json:

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

Tabii ki, burada klasör dist- modülünüzün dosyalarını sakladığı yer.


Sorunuza ve son günlerde birçok kez cevabınıza geldim ve eksik olduğum şeyin bu türleri bir .d.ts dosyasında bildirmek olduğunu eklemek istiyorum, bu yüzden benim durumumda, olmadan gelen düğüm modülleri takıldı türleri (ve ben kendi türlerinde açıklık yükleyemedi) "declare module 'MYDesiredModule'
Juan

Teşekkürler. Benim paketlerim için "typings": "dist / index" ekleniyor. TypeScript kullanmıyorum bile VS Code bir daktilo hatası atar garip
phocks 17:18

Anlayışınız için teşekkür ederiz! Tanımlara gitmeye çalışırsam VS Kod tanımlarının neden kendi npm paketim için çalışmadığını söyleyebilir misiniz? Burada bir soru oluşturdum ve şu ana kadar hiç şansım olmadı ... stackoverflow.com/questions/59128917/…
tonix

dist klasörüne "index.d.ts" dosyasını eklemeniz ve declare module "moduleName" bu arada koymanız gerekir
Sunny Sun

43

TypeScript temel olarak Javascript'teki kısıtlamaların olmaması nedeniyle kuralları daha net ve daha doğru hale getirmek için kuralları uygular ve kodunuza türler ekler. TypeScript, verilerinizi tanımlamanızı gerektirir, böylece derleyici kodunuzu kontrol edebilir ve hatalar bulabilir. Derleyici, uyumsuz türleri kullanıp kullanmadığınızı, kapsamınızın dışındaysanız veya farklı bir tür döndürmeye çalıştığınızda size bildirir. Bu nedenle, TypeScript ile harici kitaplıklar ve modüller kullanırken, bu koddaki türleri tanımlayan dosyaları içermeleri gerekir. Bu dosyalara uzantısı olan tür bildirim dosyaları denir d.ts. Npm modülleri için bildirim türlerinin çoğu zaten yazılmıştır ve bunları kullanarak ekleyebilirsiniz npm install @types/module_name(burada module_name, türlerini eklemek istediğiniz modülün adıdır).

Ancak, tür tanımları olmayan modüller vardır ve hatayı ortadan kaldırmak ve modülü kullanarak içe aktarmak için projenizin kökünde import * as module_name from 'module-name'bir klasör typingsoluşturun, içinde modül adınızla yeni bir klasör oluşturun ve klasör bir module_name.d.tsdosya oluştur ve yazdeclare module 'module_name' . Bundan sonra sadece gidin tsconfig.jsondosya ve eklemek "typeRoots": [ "../../typings", "../../node_modules/@types"]de compilerOptionssizin kütüphaneler ve modüllerin tipleri tanımlarını bulmak ve yeni bir özellik ekleyebilir typescript haberdar etmenin (sizin klasörlere uygun göreli yolu ile) "exclude": ["../../node_modules", "../../typings"]dosyaya. Tsconfig.json dosyanızın nasıl olması gerektiğine dair bir örnek:

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

Bunu yaptığınızda, hata giderilir ve en son ES6 ve TypeScript kurallarına bağlı kalabilirsiniz.


Sadece daktilo dosyasını adlandırırsam benim için çalıştı index.d.ts. Bunun dışında, benim için her yerde çalışan tek çözüm buydu.
Chris Haines

21

Bunu okuyan herkes için .js dosyanızı .ts olarak yeniden adlandırmayı deneyin.

Düzenle: "allowJs": truetsconfig dosyanıza da ekleyebilirsiniz .


evet, "tepki füzyon şemaları" ile aynı sorunu vardı ve bu çözüm bir cazibe gibi çalıştı.
yawningphantom

16

Bu şekilde benim için çalışıyor:

1. index..ts (belki de proje kökünün altında) gibi bir bildirim dosyasına kendi bildiriminizi ekleyin
declare module 'Injector';
2. index.d.ts'inizi tsconfig.json dosyasına ekleyin
  {
    "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
    }

- değiştir: modül adı etrafında gerekli tırnak işaretleri


4

Aynı sorunu daktiloda yazılmış bir reaksiyon uygulaması ile bir düğüm modülü kullanarak yaşadım. Modül kullanılarak başarıyla kuruldu npm i --save my-module. Javascript ile yazılır ve bir Clientsınıf dışa aktarılır.

İle:

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

Derleme şu hatayla başarısız olur:

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-modulemevcut olmadığından , önerilen satırla içe aktarılan my-module.d.tsdosyanın yanına bir dosya ekledim my-module. Sonra hatayı aldım:

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

İstemci aslında dışa aktarılır ve bir js uygulamasında kullanırsam normal çalışır. Ayrıca, önceki mesaj bana derleyicinin doğru dosyaya baktığını söyler ( elemanda /node_modules/my-module/lib/index.jstanımlanır my-module/package.json "main").

Derleyiciyi dolaylı olarak umursamadığımı söyleyerek sorunu çözdüm any, yani dosyanın falseaşağıdaki satırına ayarladım tsconfig.json:

    "noImplicitAny": false,

14
Yani, bu işe yarıyor, ancak kodunuzun geri kalanını kesinlikle yazma yeteneğini kaybediyorsunuz. Harika bir çözüm değil.
19:15, phillyslick

3

düzeltmek için basit:

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

nesnenin arayüzünü beyan etmek istiyorsanız (büyük proje için tavsiye edin) şunları kullanabilirsiniz:

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

Nasıl kullanılır? basit..

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

2

Bunu da alıyordum, modül ve tipler zaten kurulmuş ve IDE'mi birkaç kez yeniden yüklerken bile bir süre şaşkına dönmüştüm.

Benim durumumda düzeltilen şey, terminal işlemlerini sonlandırmak node_modules, düğüm paketi yöneticisi önbelleğini temizlemek ve yeni bir işlem yapmak ve installardından editörü yeniden yüklemekti.


2

Ne yazık ki, paket yazarının bir bildirim dosyası ile uğraşıp çıkmadığı bizim elimizde değil. Ne yapmak eğilimindedir index.d.tsçeşitli paketlerdeki tüm eksik bildirim dosyaları içeren bir dosya var :

Index.ts:

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

0

Burada her şeyi denedim, ama benim için tamamen farklı bir konuydu: *.d.tsHerhangi bir ithalat beyanlarımdan kaldırmak zorunda kaldım :

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

Hatayı kaldırdıktan sonra gitti ...

Açıklama : *.d.tsDosyadaki bir modülü bildirdiğimizde, modül otomatik olarak Typcript derleyicisi tarafından bir ortam modülü olarak (açıkça içe aktarmanız gerekmeyen modül) alınır. import ... from ...Dosyayı belirttikten sonra , dosya artık normal (ES6) bir modül haline gelir ve bu nedenle otomatik olarak alınmaz. Dolayısıyla, yine de bir ortam modülü gibi davranmasını istiyorsanız, aşağıdaki gibi farklı bir içe aktarma stili kullanın:

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


-4

Aşağıdaki kodu aşağıdaki gibi kullanarak içe aktarabilirsiniz:

var _ = require('your_module_name');
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.