打字稿。导入“模块/子目录”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-safetsconfig.json 文件无效,因此不会强制tsc 加载vee-type-safe/declarations/is-iso-date.d.ts。对于vee-type-safe 的导入,这是可以的,因为vee-type-safe/package.jsontypes 字段重定向到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 文件将导入真实路径或带有引用真实路径的maintypes 字段的package.json 文件。 (更新:看起来 main 就足够了,因为 TypeScript 会尝试更改 main 路径的扩展名。)

更多讨论请参见this issue。

【讨论】:

谢谢,我已经使用 4-th 选项解决了这个问题,我的 express 子模块有一个单独的 package.json,尽管我只指定了 "main": "../build/express/index.js 属性而没有 "types" 和一切正常,嗯...我什至不知道为什么(。但是,谢谢你的精彩解释)

以上是关于打字稿。导入“模块/子目录”npm 包时未找到环境声明的主要内容,如果未能解决你的问题,请参考以下文章

发布新的 NPM 包时未找到 E404

Swiper - 没有找到依赖打字稿,离子-vue

在打字稿进口NPM包

将打字稿路径别名编译为 NPM 发布的相对路径?

导入 config.json 文件时打字稿总是出错

ng构建无法从Git Bash中找到打字稿模块