Я разрабатываю библиотеку под названием 'vee-type-safe' для проверки типов во время выполнения. Все работало прекрасно, пока я не добавил подкаталог /express и файл /express/index.ts, куда я экспортирую некоторые фабрики проверки типов промежуточного программного обеспечения ExpressJS.
Итак, у меня есть следующая структура:
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 я импортирую модуль '../index.ts' ядра моей библиотеки.
В моем основном модуле у меня есть следующий импорт:
import isISODate = require('is-iso-date');
Пакет 'is-iso-date' не имеет типизации, поэтому я создал каталог declarations с is-iso-date.d.ts, который очень прост:
declare module 'is-iso-date' {
function isISODate(suspect: string): boolean;
export = isISODate;
}
Я добавил "typeRoots": [ ..., "declarations"] в tsconfig.json
Я добавил "types": "build/index.d.ts" в package.json
Когда я запускаю tsc в своем пакете, все компилируется без ошибок.
Но когда я устанавливаю свою библиотеку 'vee-type-safe' как зависимость от какого-то проекта через npm и пытаюсь ее скомпилировать, я получаю следующую ошибку:
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');
Это происходит только тогда, когда я импортирую подмодуль 'vee-type-safe/express'. Когда я импортирую свой основной модуль 'vee-type-safe', ошибок не возникает. Что мне здесь не хватает?
Я создал репозиторий github с минимальным проектом, чтобы продемонстрировать эту ошибку






Когда вы запускаете tsc во внешнем проекте, файл tsconfig.json для vee-type-safe не действует, поэтому ничто не заставляет tsc загружать vee-type-safe/declarations/is-iso-date.d.ts. Для импорта vee-type-safe это нормально, потому что поле types в vee-type-safe/package.json перенаправляет на vee-type-safe/build/index.d.ts, который не относится к is-iso-date, поскольку vee-type-safe/index.ts использует is-iso-date только в реализации и не раскрывает какие-либо типы из него. Однако импорт vee-type-safe/express обходит vee-type-safe/package.json и загружает vee-type-safe/express/index.ts напрямую, а этот файл импортирует vee-type-safe/index.ts, который импортирует is-iso-date, и вы получаете сообщение об ошибке. Что еще более важно, импорт vee-type-safe/express не будет работать во время выполнения, потому что он не преобразуется в файл .js.
У вас есть несколько способов исправить это, но ни один из них не подходит:
vee-type-safe/build/express, который будет преобразован в vee-type-safe/build/express/index.d.ts.outDir из vee-type-safe, чтобы файлы .d.ts создавались вместе с файлами .ts.vee-type-safe/express (и каждый другой путь подмодуля, который вы хотите, чтобы другие проекты могли импортировать) индивидуально в соответствующие файлы в build, вручную создав либо пару файлов .js и .d.ts, которые импортируют реальные пути, либо файл package.json с полями main и types которые относятся к реальным путям. (Обновление: похоже, что main достаточно, потому что TypeScript попытается изменить расширение пути main.)См. Эта проблема для дополнительного обсуждения.
Спасибо, я уже решил эту проблему, используя 4-й вариант с индивидуальным
package.jsonдля моего подмодуляexpress, хотя я указал только свойство"main": "../build/express/index.jsбез"types", и все работает нормально, Хм... Я даже не знаю почему (. Однако, спасибо за прекрасное объяснение)