TypeScript. "module/subdirectory" npm paketini içe aktarırken ortam bildirimi bulunamadı


Çalışma zamanında tip kontrolü için 'vee-type-safe' adında bir kütüphane geliştiriyorum. Her şey mükemmel çalışıyordu ta ki bir alt dizin /express ve bazı ExpressJS ara katman (middleware) tip kontrolü fabrikalarını ihraç ettiğim bir dosya /express/index.ts ekleyene kadar. Yani yapım şu şekilde:

vee-type-safe
|- build
|- package.json
|- declarations
|  |- is-iso-date.d.ts
|
|- tsconfig.json
|- index.ts       // lightweight core library
|- express
   |-index.ts     // express middleware factories

express/index.ts dosyasında kütüphanemin çekirdek '../index.ts' modülünü ithal ediyorum. Çekirdek modülümde aşağıdaki ithalat var:

import isISODate = require('is-iso-date');

'is-iso-date' paketinin tipi yok, bu yüzden is-iso-date.d.ts ile birlikte declarations dizinini oluşturdum ve bu kadar basit:

declare module 'is-iso-date' {
    function isISODate(suspect: string): boolean;
    export = isISODate;
}

Ben tsconfig.json'e "typeRoots": [ ..., "declarations"] ekledim

Ben package.json'a "types": "build/index.d.ts" ekledim

Paketimde tsc çalıştırdığımda her şey hatasız derleniyor. Ama 'vee-type-safe' kütüphanemi bir projeye npm aracılığıyla bağımlılık olarak kurup derlemeye çalıştığımda, aşağıdaki hatayı alıyorum:

Could not find a declaration file for module 'is-iso-date'. 
'/home/tegeran/projects/is-iso-date-issue/node_modules/is-iso-date/index.js'
implicitly has an 'any'type.
Try `npm install @types/is-iso-date` if it exists or add a new declaration (.d.ts)
file containing `declare module 'is-iso-date';`

1 import isISODate = require('is-iso-date');

Bu, yalnızca 'vee-type-safe/express' alt modülünü içe aktardığımda oluyor. Temel 'vee-type-safe' modülümü içe aktardığımda herhangi bir hata oluşmuyor. Burada neyi kaçırıyorum? Bu hatayı göstermek için minimum bir proje ile bir Github deposu oluşturdum.

Cevap #1

Dış projede tsc çalıştırdığınızda, vee-type-safe dosyasının tsconfig.json dosyası etkili olmaz, bu yüzden hiçbir şey tsc'yi vee-type-safe/declarations/is-iso-date.d.ts dosyasını yüklemeye zorlamaz. vee-type-safe ithali için bu sorun değildir çünkü vee-type-safe/package.json dosyasındaki types alanı vee-type-safe/build/index.d.ts dosyasına yönlendirir ve bu dosya is-iso-date'e başvurmaz; çünkü vee-type-safe/index.ts sadece uygulamada is-iso-date'i kullanır ve ondan herhangi bir tip ifadesi dışarıya aktarmaz. Ancak, vee-type-safe/express dosyasının bir importu vee-type-safe/package.json dosyasını atlar ve doğrudan vee-type-safe/express/index.ts dosyasını yükler, ve o dosya vee-type-safe/index.ts dosyasını import eder, bu da is-iso-date dosyasını import eder ve hatayı alırsınız. Daha da önemlisi, vee-type-safe/express dosyasının importu çalışma zamanında işe yaramaz çünkü bir .js dosyasına çözülmez.

Bunu düzeltmek için birkaç seçeneğiniz var, hiçbiri harika değil:

  1. (Silindi)
  2. Dış projenin vee-type-safe/build/express'i içe aktarmasını sağlayın, bu vee-type-safe/build/express/index.d.ts'ye çözümlenecektir.
  3. outDir seçeneğini vee-type-safe'ten kaldırın, böylece .d.ts dosyaları .ts dosyalarının yanında oluşturulsun.
  4. vee-type-safe/express (ve diğer projelerin import edebilmesini istediğiniz her alt modül yolunu) tek tek build altındaki doğru dosyalara yönlendirin; bunu ya gerçek yolları import eden bir .js ve .d.ts dosya çifti oluşturmak ya da main ve types alanları gerçek yolları gösteren bir package.json dosyası oluşturarak yapabilirsiniz. (Güncelleme: Görünüşe göre sadece main yeterli çünkü TypeScript main yolunun uzantısını değiştirmeyi deneyecektir.)

Ek tartışma için bu konuyu görün.