Typescript cannot find type in definition file in node_modules folder
Asked Answered
G

4

7

I have a project which has this structure:

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

I have the following ./package.json:

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

My ./src/browser/tsconfig.json is:

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

As you can see I am including also folder definitions as there are some manual definitions I want to include in all Typescript files of my project.

Problem

The following fails compilation:

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

With error:

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

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

interact is not found even though in node_modules/interactjs file index.d.ts is present with all the definitions.

What is the problem?

Groin answered 26/12, 2018 at 22:43 Comment(5)
Where is the type definition file for interactjs? Is it at project/node_modules/inderactjs/index.d.ts?Edholm
@JesseHallett Yes! It is in that lolationGroin
I have edited the question so that the file tree reflects that fact :)Groin
Did you put index.d.ts there? I don't see that file when I install the package. If you put it there then the fix is in my answer below: move the definition file to project/node_modules/interactjs/dist/interact.d.ts.Edholm
Anybody here from typescript 5, it's probably because of this: devblogs.microsoft.com/typescript/announcing-typescript-5-1/…Dourine
L
6

If you wish to keep module resolution to none adding the typing file into the "include" section should give you the output desired.

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)

built 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);
Lit answered 27/12, 2018 at 1:8 Comment(1)
It works, but the documentation says nothing about this.According to the doc, if I include in typeRoots a folder, all subfolders containing an index.d.ts will be considered. Why is typeRoots related to module?Groin
E
5

When you import a package Typescript (and Node) determine which file/module to import from that package by looking for a main field in the package.json file included with the package. The package.json file in interactjs includes this line:

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

That means that the main module in the interactjs package is named interact.js, and it is in the dist/ directory.

If the package.json file of the package does not explicitly specify the location of a type definition file, Typescript will assume that the type definition file has the same base name and location as the package's main module. Given the location of the main module in interactjs, Typescript will look for type definitions in the file dist/interact.d.ts. Try renaming the type definition file from index.d.ts to interact.d.ts, and make sure that it is in the dist/ directory.

If you are authoring a package that includes Typescript definitions it is helpful to make the location of the definition file explicit by including a types field in your package.json field as is described in the publishing guide

Edholm answered 26/12, 2018 at 23:7 Comment(2)
I am not sure I understand what you are saying. Can you process your answer a little more please? Thanks. I do not see any main entry in the documentation of the tsconfig :(Groin
@Groin I added some detail about what "main module" means. Please not that I did not say anything about tsconfig. All of the discussion in this answer relates to the package.json file in the dependent package.Edholm
S
3

It looks like you're missing the line "moduleResolution":"node", in your tsconfig.json.

This is what one of my tsconfig.json files looks like.

{
  "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"
    ]
  }
}
Sweetbread answered 26/12, 2018 at 22:59 Comment(1)
Thanks for the answer, but unfortunately it does not work and it is logic. By looking at the doc you can see that since I specified none as module, then the value is defaulted to Node for module resolution.Groin
G
-2

I fixed a similar problem by creating .yarnrc.yml at the yarn project root (not necessarily the git checkout directory because the yarn root can be a subdirectory in the git project). I filled it as follows:

nodeLinker: node-modules

yarnPath: .yarn/releases/yarn-4.1.1.cjs

This caused yarn to create directory node_modules at the yarn project root instead of somewhere else. Now VSCode can find the types.

I did so based on: Yarn v3.0.2 Why do not install the node_modules folder ? Need to run npm install after the yarn's commands?

Guaco answered 31/5, 2024 at 17:57 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.