Introduction - The Struggle is Real
Ever had one of those days when your code just stubbornly refuse to cooperate, throwing errors that makes no sense and you are just getting crazy trying to fix them? I bet you had!
For me it happened yesterday! I was working on the backend for my project and I wanted to work with TypeScript and Express. I worked with Express before, but with JavaScript instead. So I just thought, what could go wrong? And just right then the world started to fall apart...
Does TS1259: Module 'cors' can only be default-imported using the 'esModuleInterop' flag sounds familiar to you? Or what about error TS1192: Module 'cors' has no default export? It certainly does to me! So let's fix them!
The Nightmare Unfolds - The Root of All Problems
1. First Problem - Outdated Dependencies
My code was very basic:
import express from 'express';
import dotenv from 'dotenv';
import cors from 'cors';
dotenv.config();
const app = express();
app.use(cors());
app.use(express.json());
app.post('/api/register', (req, res) => {
const { username } = req.body;
if (!username) {
return res.status(400).json({
success: false,
message: 'Username is required'
});
}
return res.status(201).json({
success: true,
message: `Hello, ${username}!`
});
});
const PORT = process.env.PORT || 5000;
app.listen(PORT, () => {
console.log(`Server listening on PORT: ${PORT}`);
});
But somehow I would get this huge weird error, basically from nowhere:
No overload matches this call.
The last overload gave the following error.
Argument of type '(req: Request<{}, any, any, ParsedQs, Record>, res: Response, number>, next: NextFunction) => Response<...>' is not assignable to parameter of type 'Application>'.
Type '(req: Request<{}, any, any, ParsedQs, Record>, res: Response, number>, next: NextFunction) => Response<...>' is missing the following properties from type.
Basically it said I was poorly using a middleware somewhere, but I didn't have any except express.json()... I initially thought TypeScript was somehow breaking my code, so I applied the any
type as a workaround — just to see if the return type of the route’s callback was causing the issue. Strangely, the error disappeared. But I knew this wasn’t the proper TypeScript approach. I searched online, chatted with AI, double-checked everything… but nothing in my code seemed to be wrong.
The fix: I deleted node_modules, package.json, and package-lock.json, then reinstalled only the necessary dependencies from scratch. That resolved the issue. The root cause seemed to be mismatches between my installed dependencies, their type definitions, and my current project configuration. Even though the project was only a few days old, some of the dependencies were already outdated or incompatible, which caused things to break.
2. Second Problem - Default Imports Confusion
I was happy all the problems have completely gone. But have they? I compiled the code and tried to run the server. There were no visible VS Code errors, like nasty red squiggles. But the console said otherwise:
Can only be default-imported using the 'esModuleInterop' flag
Module has no default export
So the console said somewhere in my tsconfig.json esModuleInterop flag (that allow default-style imports (import express from 'express') from CommonJS modules) should be set to true. But in my config the flag was already set to true:
{
"extends": "@tsconfig/node22/tsconfig.json",
"compilerOptions": {
"rootDir": "./src",
"outDir": "./dist",
"noEmitOnError": true,
"esModuleInterop": true
},
"include": ["src/**/*.ts"],
"exclude": ["node_modules"]
}
I struggled and I thought and finally found a workaround that looks weird to me and unclear, but it at least fixed the errors. It imports the entire module namespace (* as ...) and then checks if the module has a .default export. If it does, it uses that; otherwise, it falls back to the full module.
In plain terms: "Use module.default if it exists (like in ESM), otherwise just use the module itself (like in CommonJS)."
import * as corsExports from 'cors';
import * as expressExports from 'dotenv';
const cors = (corsExports as any).default || corsExports;
const express = (expressExports as any).default || expressExports;
const app = express();
app.use(cors());
The fix: I wasn’t comfortable using any — it felt like a shortcut, not a proper solution. So I removed the workaround and rewrote the imports the clean way, just like before. Then I double-checked that my tsconfig.json had "esModuleInterop": true
, and my package.json included "type": "module". Finally, I deleted the old server.js (compiled output) and recompiled the project from scratch. I even restarted VS Code, sometimes can help! To my surprise — it worked! No more errors.
If you change tsconfig.json, but don't recompile everything or delete old compile output, old, outdated and incompatible code could still be running. So keep in mind, always reset your output and recompile after changes.
Conclusion
This experience taught me how easily small configuration mismatches in TypeScript and Node.js can lead to confusing errors — even when the code looks correct. Using any
might hide the problem temporarily, but the real fix comes from understanding and properly setting up the environment.
Once I cleaned up my outdated dependencies, enabled esModuleInterop, set "type": "module" in package.json, and recompiled everything cleanly, everything worked exactly as expected. From now on, I’ll know to check the config first — not just the code.
So let's talk, really waiting for your feedback! How do you fix stubborn TypeScript errors in Node.js projects? What are your debugging strategies?
Top comments (3)
I can say that after reading your post, I felt a huge 'boost of encouragement' to learn Express… 😩😂I was kinda scared to start learning Express, but now my fear’s only gotten bigger 😩😂I’m sorry you went through those problems, but I’m glad you shared your bugs with us.
I believe, coding can be really challenging sometimes, but every bug you face is just another step toward becoming a better developer.🥰🥰 Keep pushing through, your hard work will definitely pay off! Thanks to your post, I have a way to get around them if I encounter them in the future!🥰🤗 Keep up the good work on your website!🥰
Thank you! I am sorry if I scared you, but we have to learn what scares us. :) That's where real growth happen. I am glad my post was helpful!
That's truly right!🥰 🤗