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:
- 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
- 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.