TS文件使用CJS require语法无类型提示问题求助
问题分析与解决方案
核心原因
你遇到的问题源于TypeScript在Node16模块解析模式下,对.ts文件中原生CJS语法module.exports的类型推断限制:
- 在
Node16模式中,.ts文件默认被当作ESM模块处理(即使你写了CJS语法),此时module.exports属于ESM对CJS的兼容写法,但TypeScript的类型系统不会自动将其识别为可被require读取的明确类型,导致导入后类型为any。 - 而
.cts文件会被明确标记为CJS模块,export =(TypeScript兼容CJS的语法)也能让类型系统正确关联导出与导入的类型。
解决方案(按优先级排序)
1. 改用.cts后缀编写CJS类型文件
将你的TS文件重命名为.cts后缀(表示CJS TypeScript),让TypeScript明确识别模块类型:
// myError.cts module.exports = class MyError extends Error { // 类实现 } // main.cts const MyError = require("./myError");
此时VS Code会正常显示MyError的构造函数类型,实例化也会有类型检查。
2. 在.ts文件中使用export =替代module.exports
如果不想修改文件名,用TypeScript专门为兼容CJS设计的export =语法:
// myError.ts class MyError extends Error { // 类实现 } export = MyError;
导入时保持require语法不变:
// main.ts const MyError = require("./myError");
export =会告诉TypeScript这是一个CJS风格的默认导出,类型系统能正确关联require的返回类型。
3. 切换tsconfig的模块模式为CommonJS
如果你的项目不需要ESM/CJS混合支持,直接修改tsconfig配置:
{ "module": "CommonJS", "moduleResolution": "Node" }
此模式下,所有.ts文件都会被当作CJS模块处理,module.exports和require的类型提示会完全正常工作,无需修改代码语法或文件名。
验证说明
以上方案均不需要改用ESM的import/export语法,完全符合你保持CJS代码一致性的需求,同时解决类型提示缺失的问题。
内容的提问来源于stack exchange,提问作者zino
相关产品推荐
相关产品推荐

