#types/node not showing types - node.js

I've installed #types/node
In an index.ts files, the default node modules are of type any
const fs = require('fs');
fs is any.
{
"ts-node": {
"cwd": "/Users/georgenorris/Code/take-homes/simple-chat",
"projectSearchDir": "/Users/georgenorris/Code/take-homes/simple-chat"
},
"compilerOptions": {
"typeRoots": ["./node_modules/#types"],
"lib": ["es2021"],
"module": "commonjs",
"target": "es2021",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"types": ["node"],
"sourceMap": true,
"inlineSourceMap": false,
"inlineSources": true,
"declaration": false,
"noEmit": false,
"outDir": "./.ts-node"
}
}
Is my tsconfig file
Why don't the types show up?

require('modulename') is considered a dynamic import by typescript. So doesn't think it can reliably know what types to import.
In typescript you want to use the import keyword.
import fs from 'fs'
See Playground

Related

Issues compiling nodejs code with ts-node (Cannot use import statement outside a module)

When attempting to compile typescript code with NodeJS using the following command:
npx ts-node src/server.ts
I receive the following error:
SyntaxError: Cannot use import statement outside a module
I followed the instructions suggested by the error:
Warning: To load an ES module, set "type": "module" in the
package.json or use the .mjs extension.
But upon following these, I still had no luck and another error was thrown instead.
Here is the content of my server.ts file.
import App from './app';
const app = new App();
app.listen(3080);
tsconfig.json contents:
{
"compileOnSave": false,
"compilerOptions": {
"target": "ES2017",
"lib": ["es2017"],
"typeRoots": ["node_modules/#types"],
"allowSyntheticDefaultImports": true,
"experimentalDecorators": true,
"emitDecoratorMetadata": true,
"forceConsistentCasingInFileNames": true,
"module": "commonjs",
"pretty": true,
"sourceMap": true,
"declaration": true,
"outDir": "./dist",
"allowJs": true,
"noEmit": false,
"esModuleInterop": true,
"resolveJsonModule": true,
"importHelpers": true,
"baseUrl": "src",
"skipLibCheck": true,
"paths": {
"#/*": ["*"],
}
},
"include": ["src/**/*.ts", "src/**/*.json", ".env"],
"exclude": ["node_modules"]
}
I'm not really sure what is causing this but would greatly appreciate some wisdom on the issue.
Ideally i'd like to load the app via the server.ts file, while maintaining TypeScript contents.
You may need "moduleResolution": "node" in the compilerOptions for ts to recognize these types of imports.

How can CommonJS and ES6 modules be included in the same repo?

I have a NestJS/Typescript backend where I am trying to use two different third-party services that use different importing formats. The two are below:
PDFTron uses: const { PDFNet } = require('#pdftron/pdfnet-node');
Prisma uses: import { PrismaClient } from '#prisma/client'
I have asked PDFTron support to see if an module import style similar to Prisma works for their service, but they have told me it doesn't. So, how can I use both third parties if PDFTron doesn't work in Typescript files?
For reference, my tsconfig file contains the below:
{
"compilerOptions": {
"target": "es5",
"lib": ["dom", "dom.iterable", "esnext"],
"baseUrl": "./",
"allowJs": true,
"skipLibCheck": false,
"strict": false,
"strictNullChecks": true,
"forceConsistentCasingInFileNames": true,
"noEmit": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"module": "commonjs",
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"jsx": "preserve",
"incremental": true,
"tsBuildInfoFile": ".tsbuildinfo"
},
"exclude": ["node_modules"],
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"]
}

How to allow aliases in a typescript/node server?

I have aliases in my client app, and I 'm trying to do the same on the backend with typescript. I wrote:
{
"compilerOptions": {
"target": "es5",
"module": "commonjs",
"lib": ["es6"],
"allowJs": true,
"outDir": "build",
"rootDir": "src",
"strict": true,
"noImplicitAny": false,
"skipLibCheck": true,
"esModuleInterop": true,
"resolveJsonModule": true,
"paths": {
"mails/*": ["src/mails/*"],
"models/*": ["src/models/*"],
"routers/*": ["src/routers/*"],
"routes/*": ["src/routes/*"],
"utils/*": ["src/utils/*"]
},
"exclude": ["node_modules"]
}
}
But then when importing a file such as: import authRouter from "routers/auth" , Typescript claims that:
Cannot find module 'routers/auth' or its corresponding type declarations.
How to allow aliases path in a node/express server?

Typescript local file class 'Cannot find module'

Having the below folder structure
- api
- routes
- meeting.ts
- models
- DynamoService.ts
tsconfig.json
{
"compilerOptions": {
"target": "ES2020",
"module": "commonjs",
"outDir": ".build",
"strict": true,
"baseUrl": "./",
"typeRoots": ["node_modules/#types"],
"types": ["node"],
"esModuleInterop": true,
"preserveConstEnums": true,
"sourceMap": true,
"allowJs": true,
"moduleResolution": "node",
"rootDir": "./",
"removeComments": true,
"noEmitOnError": true,
"noUnusedLocals": true,
"noImplicitReturns": true
},
"exclude": ["node_modules"]
}
DynamoService.ts
export class DynamoService {
...
}
meeting.ts
import { DynamoService } from 'models/DynamoService'
const dynamoService = new DynamoService()
// other Express stuff...
When testing this I receive the below runtime error
Error: Cannot find module 'models/DynamoService'
Before trying to move the functionality into a class module having some DynamoDB helper methods in meeting.ts was working just fine.
Visual Studio Code doesn't complain about anything, no compile errors.
That should be a simple task but I seem to have trouble!
There are two approaches to solve this problem.
Relative reference
You could simply change the import line like this:
import { DynamoService } from '../../models/DynamoService'
Typescript path alias
Another convenient way is to leverage this nice TypeScript feature by configuring paths in tsconfig.json:
{
"compilerOptions": {
"baseUrl": "src",
"paths": {
"models/*": ["models/*"]
},
}
See more in https://www.typescriptlang.org/tsconfig#paths or https://medium.com/slackernoon/use-typescript-aliases-to-clean-up-your-import-statements-7210b7ec2af1.

Preserve directory structure of a package for importing

I'm trying to create a package with directory structure as follow:
src/
folder1/
index.ts
...
folder2/
index.ts
...
folder3/
index.ts
...
.
.
.
And I would like to import it as import { Class1 } from '#package/folder1', import { Class2 } from '#package/folder2', etc.
At this moment, I'm able to import my classes like import { Class1 } from '#package/lib/folder1'. Is it possible to achieve my expected behavior?
tsconfig.json:
{
"compilerOptions": {
"module": "commonjs",
"declaration": true,
"removeComments": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"target": "es2017",
"sourceMap": true,
"outDir": "./lib",
"rootDir": "./src",
"rootDirs": ["./src/folder1"],
"lib": [
"es2017",
"esnext.asynciterable"
],
"typeRoots": [
"./node_modules/#types"
],
"allowSyntheticDefaultImports": true,
"forceConsistentCasingInFileNames": true,
"moduleResolution": "node",
"pretty": true,
"noEmit": false,
"esModuleInterop": true
},
"include": ["src"],
"exclude": ["node_modules", "lib"]
}
It seems this feature is not out-of-the-box in the version of Typescript I'm using (3.7.4). The package module-alias could be a workaround but it looks like Typescript 3.8 will allow adding aliases to the exports.
Typescript 3.8 announcement link
Related SO question

Resources