So as we all get the issue with types. I too got it.
What happened to me?
So I was creating a simple express server. Things were fine until I got this big error message.
pnpm dev
> @ dev D:\My Code\Projects\web-dev\full-stack\LEARNING\mycom\backend
> cross-env NODE_ENV=DEV tsx watch src/index.ts
D:\My Code\Projects\web-dev\full-stack\LEARNING\mycom\backend\node_modules\.pnpm\express@5.1.0\node_modules\express\lib\application.js:161
res.setHeader('X-Powered-By', 'Express');
^
TypeError: Cannot read properties of undefined (reading 'setHeader')
at Function.handle (D:\My Code\Projects\web-dev\full-stack\LEARNING\mycom\backend\node_modules\.pnpm\express@5.1.0\node_modules\express\lib\application.js:161:9)
at app (D:\My Code\Projects\web-dev\full-stack\LEARNING\mycom\backend\node_modules\.pnpm\express@5.1.0\node_modules\express\lib\express.js:38:9)
at express (D:\My Code\Projects\web-dev\full-stack\LEARNING\mycom\backend\src\app.ts:34:21)
at Object.<anonymous> (D:\My Code\Projects\web-dev\full-stack\LEARNING\mycom\backend\src\app.ts:41:16)
at Module._compile (node:internal/modules/cjs/loader:1358:14)
at Object.transformer (D:\My Code\Projects\web-dev\full-stack\LEARNING\mycom\backend\node_modules\.pnpm\tsx@4.20.6\node_modules\tsx\dist\register-D46fvsV_.cjs:3:1104)
at Module.load (node:internal/modules/cjs/loader:1208:32)
at Module._load (node:internal/modules/cjs/loader:1024:12)
at Module.require (node:internal/modules/cjs/loader:1233:19)
at require (node:internal/modules/helpers:179:18)
Node.js v20.15.1
I was confused I tried to rerun
tsconfig.json
{
"compilerOptions": {
"target": "es2016",
"module": "commonjs",
"lib": ["es6", "dom"],
"outDir": "./dist",
"rootDir": "./src",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"typeRoots": [
"./node_modules/@types", // Include default @types
"./src/types" // Path to your custom types directory
]
},
"include": ["src/**/*.ts", "src/types/**/*.d.ts"],
"exclude": ["node_modules", "**/*.spec.ts"]
}
backend\src\types\express.d.ts
import { User } from "../generated/prisma";
declare global {
namespace Express{
interface Request {
user?: User| null;
}
}
}
pnpm dev
> @ dev D:\My Code\Projects\web-dev\full-stack\LEARNING\mycom\backend
> cross-env NODE_ENV=DEV nodemon src/index.ts
[nodemon] 3.1.9
[nodemon] to restart at any time, enter `rs`
[nodemon] watching path(s): *.*
[nodemon] watching extensions: ts,json
[nodemon] starting `ts-node src/index.ts`
D:\My Code\Projects\web-dev\full-stack\LEARNING\mycom\backend\node_modules\.pnpm\ts-node@10.9.2_@types+node@24.7.2_typescript@5.9.3\node_modules\ts-node\src\index.ts:859
return new TSError(diagnosticText, diagnosticCodes, diagnostics);
^
TSError: ⨯ Unable to compile TypeScript:
src/middlewares/auth.middleware.ts:33:9 - error TS2339: Property 'user' does not exist on type 'Request<ParamsDictionary, any, any, ParsedQs, Record<string, any>>'.
33 req.user = user;
~~~~
src/middlewares/auth.middleware.ts:47:14 - error TS2339: Property 'user' does not exist on type 'Request<ParamsDictionary, any, any, ParsedQs, Record<string, any>>'.
47 if (!req.user) {
~~~~
src/middlewares/auth.middleware.ts:51:36 - error TS2339: Property 'user' does not exist on type 'Request<ParamsDictionary, any, any, ParsedQs, Record<string, any>>'.
51 if ( requiredRole.includes(req.user.role) === false ) {
~~~~
at createTSError (D:\My Code\Projects\web-dev\full-stack\LEARNING\mycom\backend\node_modules\.pnpm\ts-node@10.9.2_@types+node@24.7.2_typescript@5.9.3\node_modules\ts-node\src\index.ts:859:12)
at reportTSError (D:\My Code\Projects\web-dev\full-stack\LEARNING\mycom\backend\node_modules\.pnpm\ts-node@10.9.2_@types+node@24.7.2_typescript@5.9.3\node_modules\ts-node\src\index.ts:863:19)
at getOutput (D:\My Code\Projects\web-dev\full-stack\LEARNING\mycom\backend\node_modules\.pnpm\ts-node@10.9.2_@types+node@24.7.2_typescript@5.9.3\node_modules\ts-node\src\index.ts:1077:36)
at Object.compile (D:\My Code\Projects\web-dev\full-stack\LEARNING\mycom\backend\node_modules\.pnpm\ts-node@10.9.2_@types+node@24.7.2_typescript@5.9.3\node_modules\ts-node\src\index.ts:1433:41)
at Module.m._compile (D:\My Code\Projects\web-dev\full-stack\LEARNING\mycom\backend\node_modules\.pnpm\ts-node@10.9.2_@types+node@24.7.2_typescript@5.9.3\node_modules\ts-node\src\index.ts:1617:30)
at Module._extensions..js (node:internal/modules/cjs/loader:1416:10)
at Object.require.extensions.<computed> [as .ts] (D:\My Code\Projects\web-dev\full-stack\LEARNING\mycom\backend\node_modules\.pnpm\ts-node@10.9.2_@types+node@24.7.2_typescript@5.9.3\node_modules\ts-node\src\index.ts:1621:12)
at Module.load (node:internal/modules/cjs/loader:1208:32)
at Function.Module._load (node:internal/modules/cjs/loader:1024:12)
at Module.require (node:internal/modules/cjs/loader:1233:19) {
diagnosticCodes: [ 2339, 2339, 2339 ]
}
[nodemon] app crashed - waiting for file changes before starting...
Finally after the hit and trials I got it working.
package.json
scripts:{
"dev": "cross-env NODE_ENV=DEV nodemon --watch 'src/**/*.ts' --exec 'ts-node --files' src/index.ts",
"build": "tsc",
"start": "cross-env NODE_ENV=PROD node dist/index.js"
}
tsconfig.json
{
"compilerOptions": {
"target": "es2016",
"module": "commonjs",
"lib": ["es6", "dom"],
"outDir": "./dist",
"rootDir": "./src",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"typeRoots": [
"./node_modules/@types", // Include default @types
"./src/types" // Path to your custom types directory
]
},
"include": ["src/**/*.ts", "src/types/**/*.d.ts"],
"exclude": ["node_modules", "**/*.spec.ts"]
}
backend\src\types\express\index.d.ts
import { User } from "../../../generated/prisma";
declare module "express" {
export interface Request {
user?: User | null;
}
}
Now let me explain the dev script
-
Development Script:
Always use a dev script like:
"dev": "nodemon --watch 'src/**/*.ts' --exec 'ts-node --files' src/index.ts"The
--filesflag is crucial to load type augmentation files automatically. -
When you see TS errors like “Property ‘user’ does not exist on type ‘Request’”:
- Double-check module augmentation syntax.
- Make sure your dev script includes
--filesfor ts-node. - Restart your TypeScript server/IDE after changing types or config.
Top comments (0)