Home > Blockchain >  ts-node cannot import type declaration files
ts-node cannot import type declaration files

Time:10-24

node v16.11.0 ts-node v10.4.0 tsc v4.4.4

I am converting a node.js project to typescript. I would like to use typescript and nodemon for this. I feel I am almost there, however I am getting an infuriating error when I try to import my type declaration files. eg: *.d.ts

Error: Cannot find module '../types/discord' This error does not appear in-editor, as in vs-code shows the types properly and the path resolves to a file. It is only upon running ts-node ./src/index.ts that the following error is shown. npm run dev just runs nodemon, which execs ts-node ./src/index.ts...

❯ npm run dev

> <project_name>@1.0.0 dev
> NODE_ENV=development nodemon

[nodemon] 2.0.14
[nodemon] to restart at any time, enter `rs`
[nodemon] watching path(s): src/**/*
[nodemon] watching extensions: ts
[nodemon] starting `ts-node ./src/index.ts`
Error: Cannot find module '../types/discord'
Require stack:
- /Users/<me>/src/<project_name>/src/index.ts
    at Function.Module._resolveFilename (node:internal/modules/cjs/loader:933:15)
    at Function.Module._resolveFilename.sharedData.moduleResolveFilenameHook.installedValue [as _resolveFilename] (/Users/<me>/src/<project_name>/node_modules/@cspotcode/source-map-support/source-map-support.js:679:30)
    at Function.Module._load (node:internal/modules/cjs/loader:778:27)
    at Module.require (node:internal/modules/cjs/loader:1005:19)
    at require (node:internal/modules/cjs/helpers:102:18)
    at Object.<anonymous> (/Users/devin/src/wordsmith/src/index.ts:4:1)
    at Module._compile (node:internal/modules/cjs/loader:1101:14)
    at Module.m._compile (/Users/devin/src/wordsmith/node_modules/ts-node/src/index.ts:1371:23)
    at Module._extensions..js (node:internal/modules/cjs/loader:1153:10)
    at Object.require.extensions.<computed> [as .ts] (/Users/<me>/src/<project_name>/node_modules/ts-node/src/index.ts:1374:12) {
  code: 'MODULE_NOT_FOUND',
  requireStack: [ '/Users/<me>/src/<project_name>/src/index.ts' ]
}
[nodemon] app crashed - waiting for file changes before starting..

-Edit- I can even remove the import statement and my editor will still see the type file correctly. Even tsc will work. But ts-node, for some reason, does not.

[nodemon] restarting due to changes...
[nodemon] starting `ts-node ./src/index.ts`
/Users/<me>/src/<project>/node_modules/ts-node/src/index.ts:750
    return new TSError(diagnosticText, diagnosticCodes);
           ^
TSError: ⨯ Unable to compile TypeScript:
src/index.ts:11:8 - error TS2339: Property 'commands' does not exist on type 'Client<boolean>'.

I don't understand why this isn't working. I know the file is in the correct location and is being imported correctly for the TS application. However ts-node, specifically, cannot resolve it.

Any help would be appreciated. Here is my tsconfig.json:

{
  "compilerOptions": {
    "rootDir": "./src",
    "typeRoots": [
      "./src/@types",
      "./node_modules/@types",
    ],
    "outDir": "./dist",
  },
  "exclude": ["node_modules"],
  "extends": "@tsconfig/node16/tsconfig.json",
}

I'd even like recommendations for other tools to use, if ts-node just isn't how this is done any longer. I've spent more time getting type declarations working than on the actual project.

CodePudding user response:

Have you tried to:

  1. Install discord types? Sometimes packages say they come with Type Decalations but some in the declarations are missed until the package is updated. So try: npm install discord.js @discordjs/rest discord-api-types. This will install types in both the rest client as well the api types which I think is what you're missing
  2. Also check in node_modules/discord/package.json file, you will find this line "types": "" and if it's empty then change the value to "./typings/index.d.ts" so now it looks like "types": "./typings/index.d.ts"

CodePudding user response:

Here's what I had to do. I finally got it. I'm obviously not that experienced with typescript, so it may not be the ideal answer and I appreciate feedback.

First, I had to change the command to this: ts-node --files ./src/index.ts

This flag says to use the tsconfig's include and exclude section on startup.

Second, I included those sections like this:

{
  "compilerOptions": {
    "typeRoots": [
      "./src/@types",
      "./node_modules/@types",
    ],
    "outDir": "./dist",
  },
  "include": ["./src"],
  "exclude": ["./node_modules"],
  "extends": "@tsconfig/node16/tsconfig.json",
}

Third, I put all my types into these paths:

src/@types/discord.d.ts src/@types/project.d.ts

Fourth, I then had to remove all of the import statements to types! Now ts-node wouldn't break on them!

Fifth, I then made the discord type file, which contained only one update to an existing type, look like this:

import { Collection } from 'discord.js';

declare module 'discord.js' {
  export interface Client {
    commands: Collection<unknown, any>
  }
}

and my existing types in the project file, which look like this:

interface Command {
  name: string,
  helpText: string,
  parameters: string[],
  callback: handlerCallback,
}

<other types here>

Note that the declared modules include imports and exports, and are therefore a module. While the project types file has no imports or exports. Both worked by using the --files flag with ts-node and then using my tsconfig to specify where all the typings are. Finally. I can have nodemon/ts-node and tsc work on the same codebase.

  • Related