【问题标题】:Typescript cannot find type in definition file in node_modules folderTypescript 在 node_modules 文件夹的定义文件中找不到类型
【发布时间】:2018-12-26 22:43:01
【问题描述】:

我有一个具有这种结构的项目:

project/
├── package.config
├── node_modules/
│   ├── interactjs/
│   ├── ├── index.d.ts
├── src/
│   ├── browser/
│   |   ├── tsconfig.json
│   |   ├── index.ts

我有以下./package.json

{
    ...
    "dependencies": {
        "interactjs": "1.3.4"
    },
    "devDependencies": {
        "typescript": "3.2.2"
    }
}

我的./src/browser/tsconfig.json 是:

{
    "compilerOptions": {
        "target": "es5",
        "module": "none",
        "declaration": true,
        "strict": true,
        "strictNullChecks": false,
        "outDir": "./out"
    },
    "typeRoots": [
        "../../node_modules",
        "../../node_modules/@types",
        "../definitions"
    ],
    "include": [
        "./**/*"
    ]
}

如您所见,我还包括文件夹 definitions,因为我想在项目的所有 Typescript 文件中包含一些手动定义。

问题

以下编译失败:

const p : interact.Position = { x: 1, y: 2 };

有错误:

index.ts:9:11 - error TS2503: Cannot find namespace 'interact'.

9 const s : interact.Position = { x: 1, y: 2 };
            ~~~~~~~~

即使在node_modules/interactjs 文件中index.d.ts 包含所有定义,也找不到interact

有什么问题?

【问题讨论】:

  • interactjs的类型定义文件在哪里?是project/node_modules/inderactjs/index.d.ts吗?
  • @JesseHallett 是的!就是这样
  • 我已经编辑了这个问题,以便文件树反映这个事实:)
  • 你把 index.d.ts 放在那里了吗?安装软件包时看不到该文件。如果你把它放在那里,那么修复就在我下面的答案中:将定义文件移动到project/node_modules/interactjs/dist/interact.d.ts

标签: javascript typescript definition


【解决方案1】:

如果您希望将模块分辨率保持为无,将输入文件添加到 "include" 部分应该会给您所需的输出。

tsconfig.json

{
    "compilerOptions": {
        "target": "es5",
        "module": "none",
        "declaration": true,
        "strict": true,
        "strictNullChecks": false,
        "outDir": "./out",
        "noImplicitAny": false //<------ to ignore the errors in interactjs/index.d.ts
    },
    "typeRoots": [
        "../../node_modules",
        "../../node_modules/@types",
        "../definitions"
    ],
    "include": [
        "../../node_modules/interactjs/index.d.ts", //<----- include interact in the global scope
        "./**/*"
    ]
}

index.ts

const p : interact.Position = { x: 1, y: 2 };
const s : interact.SnapPosition = { x: 1, y: 2, range: 0 };

const listener : interact.Listener = (e: interact.InteractEvent)=>{
    console.log(e);
};

interact.on("cancel", listener)

构建index.js

"use strict";
var p = { x: 1, y: 2 };
var s = { x: 1, y: 2, range: 0 };
var listener = function (e) {
    console.log(e);
};
interact.on("cancel", listener);

【讨论】:

  • 它有效,但文档对此没有任何说明。根据文档,如果我在typeRoots 文件夹中包含所有包含index.d.ts 的子文件夹,将被考虑。为什么typeRootsmodule 相关?
【解决方案2】:

您的 tsconfig.json 中似乎缺少 "moduleResolution":"node", 行。

这是我的一个 tsconfig.json 文件的样子。

{
  "compileOnSave": false,
  "compilerOptions": {
  "baseUrl": "./",
  "outDir": "./dist/out-tsc",
  "sourceMap": true,
  "declaration": false,
  "module": "es2015",
  "moduleResolution": "node",
  "emitDecoratorMetadata": true,
  "experimentalDecorators": true,
  "target": "es5",
  "typeRoots": [
    "node_modules/@types"
  ],
  "lib": [
    "es2017",
    "dom"
   ]
  }
}

【讨论】:

  • 感谢您的回答,但不幸的是它不起作用,这是逻辑。通过查看doc 可以看到,由于我将none 指定为模块,因此该值默认为Node 用于模块解析。
【解决方案3】:

当您导入包时,Typescript(和 Node)通过在包中包含的 package.json 文件中查找 main 字段来确定要从该包中导入哪个文件/模块。 interactjs 中的package.json 文件包括这一行:

"main": "dist/interact.js",

也就是说interactjs包中的主模块名为interact.js,在dist/目录下。

如果包的package.json 文件没有明确指定类型定义文件的位置,Typescript 将假定类型定义文件与包的主模块具有相同的基本名称和位置。给定interactjs 中主模块的位置,Typescript 将在文件dist/interact.d.ts 中查找类型定义。尝试将类型定义文件从index.d.ts 重命名为interact.d.ts,并确保它位于dist/ 目录中。

如果您正在创作一个包含 Typescript 定义的包,那么通过在 package.json 字段中包含 types 字段来明确定义文件的位置会很有帮助,如 publishing guide 中所述

【讨论】:

  • 我不确定我是否明白你在说什么。你能再处理一下你的答案吗?谢谢。我在tsconfig 的文档中没有看到任何main 条目:(
  • @Andry 我添加了一些关于“主模块”含义的细节。请注意我没有说任何关于tsconfig 的事情。此答案中的所有讨论都与依赖包中的package.json 文件有关。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-02-24
  • 2018-01-01
  • 2021-08-27
  • 2020-02-18
  • 2018-07-20
  • 2019-04-16
  • 1970-01-01
相关资源
最近更新 更多