打字稿。导入“模块/子目录”npm 包时未找到环境声明
Posted
技术标签:
【中文标题】打字稿。导入“模块/子目录”npm 包时未找到环境声明【英文标题】:TypeScript. Ambient declaration was not found when importing "module/subdirectory" npm package 【发布时间】:2019-04-13 05:46:49 【问题描述】:我正在开发一个名为'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'
包没有类型,所以我用is-iso-date.d.ts
创建了declarations
目录,就这么简单:
declare module 'is-iso-date'
function isISODate(suspect: string): boolean;
export = isISODate;
我将"typeRoots": [ ..., "declarations"]
添加到tsconfig.json
我将"types": "build/index.d.ts"
添加到package.json
当我在我的包中运行 tsc
时,所有内容都可以编译,没有错误。
但是当我通过 npm 将我的 'vee-type-safe'
库安装为某个项目的依赖项并尝试编译它时,我收到以下错误:
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'
模块时,不会产生任何错误。我在这里想念什么?
我创建了a github repo with a bare minimum project to demonstrate this error
【问题讨论】:
【参考方案1】:当您在外部项目上运行tsc
时,vee-type-safe
的tsconfig.json
文件无效,因此不会强制tsc
加载vee-type-safe/declarations/is-iso-date.d.ts
。对于vee-type-safe
的导入,这是可以的,因为vee-type-safe/package.json
的types
字段重定向到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
。
从vee-type-safe
中删除outDir
选项,以便.d.ts
文件与.ts
文件一起生成。
通过手动创建一对 .js
和 .d.ts
文件将导入真实路径或带有引用真实路径的main
和types
字段的package.json
文件。 (更新:看起来 main
就足够了,因为 TypeScript 会尝试更改 main
路径的扩展名。)
更多讨论请参见this issue。
【讨论】:
谢谢,我已经使用 4-th 选项解决了这个问题,我的express
子模块有一个单独的 package.json
,尽管我只指定了 "main": "../build/express/index.js
属性而没有 "types"
和一切正常,嗯...我什至不知道为什么(。但是,谢谢你的精彩解释)以上是关于打字稿。导入“模块/子目录”npm 包时未找到环境声明的主要内容,如果未能解决你的问题,请参考以下文章