Typescript无法在node_modules文件夹中的定义文件中找到类型

5

我有一个项目,它的结构如下:

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吗? - Jesse Hallett
@JesseHallett 是的!就在那个位置。 - Andry
我已经编辑了问题,以便文件树反映这一事实 :) - Andry
你把 index.d.ts 放在那里了吗?当我安装包时,我没有看到那个文件。如果你把它放在那里,那么解决方法就在我的下面答案中:将定义文件移动到 project/node_modules/interactjs/dist/interact.d.ts - Jesse Hallett
有人在这里使用TypeScript 5吗?如果是的话,可能是因为这个原因:https://devblogs.microsoft.com/typescript/announcing-typescript-5-1/#explicit-typeroots-disables-upward-walks-for-node_modules-types - PitaJ
3个回答

4
如果您希望将模块解析保持为"none",则将类型文件添加到"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);

1
它能工作,但文档中没有提到这一点。根据文档,如果我在 typeRoots 中包含一个文件夹,则所有包含 index.d.ts 的子文件夹都将被视为类型根目录。为什么 typeRootsmodule 有关? - Andry

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字段来明确定义文件的位置是有帮助的,如发布指南所述。

我不确定我理解你的意思。你能再详细说明一下吗?谢谢。我在“tsconfig”的文档中没有看到任何“main”入口 :( - Andry
@Andry 我增加了一些关于“主模块”意义的细节。请注意,我没有提到tsconfig。这个答案中所有讨论都跟依赖包里的package.json文件有关。 - Jesse Hallett

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"
   ]
  }
}

1
谢谢回答,但不幸的是它不起作用并且逻辑上也有问题。从文档可以看出,由于我指定了none作为模块,则默认的模块解析值为Node - Andry

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接