TypeScript。导入“模块/子目录” npm包时找不到环境声明

时间:2018-11-09 16:13:08

标签: typescript npm module node-modules

我正在开发一个名为'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时,所有内容都会正确编译。 但是,当我通过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 个答案:

答案 0 :(得分:1)

在外部项目上运行tsc时,tsconfig.json的{​​{1}}文件无效,因此没有任何迫使vee-type-safe加载tsc的情况。对于导入vee-type-safe/declarations/is-iso-date.d.ts,这是可以的,因为vee-type-safe的{​​{1}}字段重定向到types,因为{{1} }仅在实现中使用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文件。

您有几种方法可以解决此问题,但都不是很好:

  1. (已删除)
  2. 具有外部项目导入vee-type-safe/index.ts,它将解析为is-iso-date
  3. vee-type-safe/express中删除.js选项,以便与vee-type-safe/build/express文件一起生成vee-type-safe/build/express/index.d.ts文件。
  4. 通过手动创建一对outDir和{,将vee-type-safe(以及您希望其他项目能够导入的其他子模块路径)分别重定向到.d.ts下的适当文件。导入真实路径的{1}}文件或包含引用真实路径的.tsvee-type-safe/express字段的build文件。 (更新:看起来.js就足够了,因为TypeScript会尝试更改.d.ts路径的扩展名。)

有关其他讨论,请参见this issue