通过d.ts扩展Express.User后出现TypeScript编译错误
问题描述
我在Express + Passport的TypeScript项目中,尝试通过.d.ts文件扩展Express.User类型,让req.user能携带自定义IUser的属性。但编译时始终报错Property '_id' does not exist on type 'User',尽管IDE能正常识别类型并自动补全,运行时也能打印出包含_id的用户数据。
相关代码
类型扩展文件 src/interfaces/expressExtend.d.ts
import IUser from "./src/interfaces/userInterface"; declare global { namespace Express { export interface User extends IUser {} } }
路由校验代码 index.ts
import { Request, Response } from 'express'; app.get('/auth-check', async (req: Request, res: Response) => { console.log('SESSION => ', req.session); console.log('USER => ', req.user); const userId = req.user?._id ?? undefined; // 编译报错:Property '_id' does not exist on type 'User' if (userId) { res.sendStatus(200); } else { res.sendStatus(401); } });
tsconfig.json 配置
{ "compilerOptions": { "module": "NodeNext", "target": "ES2022", "strict": true, "noUnusedLocals": true, "noImplicitReturns": true, "noFallthroughCasesInSwitch": true, "noImplicitAny": true, "esModuleInterop": true, "moduleResolution": "NodeNext", "outDir": "dist", "rootDir": "src", "typeRoots": [ "node_modules/@types", "src/interfaces"], }, "include": ["**/*.ts", "**/*.tsx", "src/**/*", "src/interfaces/expressExtend.d.ts"], "exclude": ["node_modules", "dist"] }
已尝试的无效操作
- 在
typeRoots中指定.d.ts文件路径而非仅文件夹 - 在
include中明确指定.d.ts文件路径 - 检查Passport是否覆盖自定义类型(未发现覆盖)
- 将
.d.ts文件移至项目根目录并更新引用 - 修改
.d.ts文件:移除export interface User中的export,添加空的export {} - 在
index.ts中直接导入.d.ts文件
解决方案
问题核心是NodeNext模块系统下的全局声明处理逻辑,以及类型文件的模块属性配置错误,按以下步骤修复:
1. 修正expressExtend.d.ts的模块与路径
由于文件中使用了import,会被识别为ES模块,此时必须添加export {}标记模块上下文,同时修正导入路径(原路径存在层级错误):
// src/interfaces/expressExtend.d.ts import IUser from "./userInterface"; // 从当前文件夹导入,而非上级目录 declare global { namespace Express { interface User extends IUser {} // 移除export,Express.User是全局命名空间接口,无需重新导出 } } export {}; // 标记为模块,确保全局声明生效
2. 调整tsconfig.json配置
- 移除
typeRoots中的src/interfaces:typeRoots用于指定第三方类型包目录,自定义类型通过include即可覆盖,无需放入其中 - 简化
include配置,确保覆盖所有src下的文件:
{ "compilerOptions": { "module": "NodeNext", "target": "ES2022", "strict": true, "noUnusedLocals": true, "noImplicitReturns": true, "noFallthroughCasesInSwitch": true, "noImplicitAny": true, "esModuleInterop": true, "moduleResolution": "NodeNext", "outDir": "dist", "rootDir": "src", "typeRoots": [ "node_modules/@types" ] }, "include": ["src/**/*"], "exclude": ["node_modules", "dist"] }
3. 清理缓存重新编译
执行以下命令清理TypeScript缓存并重新编译:
rm -rf node_modules/.cache npx tsc --build --clean npx tsc
内容的提问来源于stack exchange,提问作者Dan-DH
相关产品推荐
相关产品推荐

